С Новым годом! Форум программистов, компьютерный форум, киберфорум
Microsoft SQL Server
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
 Аватар для Dinkin
783 / 556 / 136
Регистрация: 31.05.2013
Сообщений: 3,145
Записей в блоге: 3

Немного теории

09.06.2018, 12:10. Показов 1161. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день! На днях на одной из конференций по MSSQL, увидил немного интересное решение, обработки данных, есть две таблицы Города и Улицы. И таблица Города содержит еще два поля, первый и послений id улиц что в него входят.
Специалисты говрят,что если держать эти два пополнительных значения, то масса привелегий при выборке, такие как уменьшается кол-во итераций, уменьшается размер кеша, быстрее освобождается таблица, снижается нагрузки на процесор и жесткие диски.
Но есть и минусы,всевремя приходтся обновлять эти первое и посление значение.
Я вот думаю,вобще стоит ли такое решение внедрять, когда в таблицах записей до миллионна, так как такое решение актуально в очень больших таблицах.
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
09.06.2018, 12:10
Ответы с готовыми решениями:

Немного не понимаю по теории sql
1. Какие конструкции языка Sql используются для задания правил поддержания целостности базы данных? 2. Что такое конструктор запросов в...

SQL немного конспекта
Здравствуйте, я студент и очень щас напряжно учится и работать так как живу в общежитии, прошу вас мне немного помочь подготовоить реферат...

Проектирование БД, возможно немного нестандартное
Доброго времени всем! В общем, в чём суть, есть одна БД. В принципе, работает не спорю, хотя, и очень давно проектировалась. А сейчас...

12
3614 / 2135 / 756
Регистрация: 02.06.2013
Сообщений: 5,169
09.06.2018, 12:23
Видимо вы не полностью озвучили предлагаемое решение.
Ибо в том, что вы написали, нет ни какого смысла.
0
 Аватар для Dinkin
783 / 556 / 136
Регистрация: 31.05.2013
Сообщений: 3,145
Записей в блоге: 3
09.06.2018, 12:31  [ТС]
Вот две таблицы:
Города
id
name


Улицы

id
name
parent_city_id

К примеру необходимо выбрать все улицы определеного города. По стандарту выборка будет идти по определному parent_city_id.

Что предлагают спецы, Они предлагают добавить в первыю таблицу еще два поля, типа так:

Города
id
name
first_id
last_id

и теперь при выборке удиц определеного города,мы берем интервал между first_id и last_id, тем самым сокращая выборку Но при этом появляется дополнительный запрос к первой таблице, что бы получить данные об интервале.
0
3614 / 2135 / 756
Регистрация: 02.06.2013
Сообщений: 5,169
09.06.2018, 12:57
Dinkin, где гарантия, что:
- между first_id и last_id улицы только нужного города?
- first_id и last_id не первая и последняя строка таблицы?
0
 Аватар для Dinkin
783 / 556 / 136
Регистрация: 31.05.2013
Сообщений: 3,145
Записей в блоге: 3
09.06.2018, 15:15  [ТС]
Цитата Сообщение от invm Посмотреть сообщение
между first_id и last_id улицы только нужного города?
Нет, могут быть разные города, но именновы браный город.только в этих пределах

Цитата Сообщение от invm Посмотреть сообщение
first_id и last_id не первая и последняя строка таблицы?
По теории, может быть и первой и посленей быть, но ссылаются, чтовероятность мала что так выподит при выборке. Идаже выпадит, то на на фоне других выборок это не критично

Добавлено через 22 минуты

Не по теме:


Сорян за грамотность, писал с телефона

0
3614 / 2135 / 756
Регистрация: 02.06.2013
Сообщений: 5,169
09.06.2018, 15:18
Dinkin, вы фантазируете, пытаясь обосновать показанное решение.

Озвученная вами задача решается правильно спроектированными индексами. Не нужны никакие приседания с дополнительными столбцами в таблице городов.

Насчет "малой вероятности" - вы добавили в таблицу все улицы Города1, затем все улицы Города2, затем еще одну улицу Города1. Что будет в результате выборки улиц Города1, пользуясь этими двумя столбцами?
1
 Аватар для Dinkin
783 / 556 / 136
Регистрация: 31.05.2013
Сообщений: 3,145
Записей в блоге: 3
09.06.2018, 15:24  [ТС]
invm, Ну вот мне интересно, что кто думает на счет этого варианта. Поже будет время, найду этот вебинар на ютуб, кину сюда ссылку.

Цитата Сообщение от invm Посмотреть сообщение
Что будет в результате выборки улиц Города1, пользуясь этими двумя столбцами?
При каждом добавлении новой улицы, значения в столбцах первой и посленей (first_id и last_id улицы) записи у города пересчитывается. И выборка покажет все как надо, тоесть все улицы (это еслия правильно понял вопрос).
0
3614 / 2135 / 756
Регистрация: 02.06.2013
Сообщений: 5,169
09.06.2018, 16:31
Цитата Сообщение от Dinkin Посмотреть сообщение
И выборка покажет все как надо, тоесть все улицы
Покажет.
Только для этого, если пользоваться first_id и last_id, придется прочитать и отфильтровать все улицы Города2.

В общем, еще раз - задача решается правильным проектированием индексов.
1
 Аватар для Dinkin
783 / 556 / 136
Регистрация: 31.05.2013
Сообщений: 3,145
Записей в блоге: 3
09.06.2018, 16:41  [ТС]
Цитата Сообщение от invm Посмотреть сообщение
Только для этого, если пользоваться first_id и last_id, придется прочитать и отфильтровать все улицы Города2.
Не, просто я ни как видимо не могу нормально объеснить, уж извиняйте...попробую с другой стороны:
1) У Города1, был интервал id улиц с 1 по 1000
2) Добавил новую улицу Городу1, и ее id стал к примеру 2015
3) Мы меняем в первой таблице у Города1 значение last_id на 2015

и следующий запрос для выборки улиц у Города1 (чей id= 1) будет типа так:

SQL
1
2
3
SELECT * FROM Улицы u
JOIN Города g ON (g.id = 1)
WHERE u.parent_city_id = 1 AND u.id>=g.first_id AND u.id<=g.last_id
Я не говрю, что это правильно, и не говрю, что не правильно =) Я увидел этот метод и стало интересно. На вебинаре показали графики быстродействия просто по ключам и поключам с этим методом при таблице свыше миллиарда строк. Разница колосальна .
Вот и решил спросить, кто об этом что думает =)
0
3614 / 2135 / 756
Регистрация: 02.06.2013
Сообщений: 5,169
09.06.2018, 21:48
Цитата Сообщение от Dinkin Посмотреть сообщение
1) У Города1, был интервал id улиц с 1 по 1000
2) Добавил новую улицу Городу1, и ее id стал к примеру 2015
3) Мы меняем в первой таблице у Города1 значение last_id на 2015
Между 1000 и 2015 улицы какого города?
Цитата Сообщение от Dinkin Посмотреть сообщение
и следующий запрос для выборки улиц у Города1 (чей id= 1) будет типа так:
SQL
1
2
3
SELECT * FROM Улицы u
JOIN Города g ON (g.id = 1)
WHERE u.parent_city_id = 1 AND u.id>=g.first_id AND u.id<=g.last_id
Какие индексы предполагаются? И как, по-вашему, будет работать этот запрос?
0
 Аватар для Dinkin
783 / 556 / 136
Регистрация: 31.05.2013
Сообщений: 3,145
Записей в блоге: 3
10.06.2018, 14:12  [ТС]
Цитата Сообщение от invm Посмотреть сообщение
Между 1000 и 2015 улицы какого города?
В этом интервале улиц, могут быть любые городоа (Город 1, Город 2...), но за пределами этого интервала не может быть Города 1.

Цитата Сообщение от invm Посмотреть сообщение
Какие индексы предполагаются? И как, по-вашему, будет работать этот запрос?
Индексы автоинкримент. И при запросе, по ключам сразу будут отброшены записи не попавшие в интервал между first_id и last_id. То есть приходится на такой запрос гораздо меньше итераций.

PS. Вчера создал тестовый стенд (БД)...тестанул, действительно есть результат, но при условии, если записей от 10 миллионов. Если записей меньше, то скорость выборки одинаковая.

На вебинаре еще дали несколько интересных предложений....так же буду тестировать.
0
3614 / 2135 / 756
Регистрация: 02.06.2013
Сообщений: 5,169
10.06.2018, 17:35
Лучший ответ Сообщение было отмечено Dinkin как решение

Решение

Цитата Сообщение от Dinkin Посмотреть сообщение
В этом интервале улиц, могут быть любые городоа (Город 1, Город 2...), но за пределами этого интервала не может быть Города 1.
Вы, похоже, так и не осознали последствий такого подхода...
Цитата Сообщение от Dinkin Посмотреть сообщение
Индексы автоинкримент
Не бывает таких индексов. Видимо, тема индексов в БД вами не изучалась.

Вот вам для анализа и размышлений:
T-SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
use tempdb;
go
 
/*Подготовка данных*/
create table dbo.Cities
(
 city_id int not null,
 city_Name varchar(50) not null,
 city_LeftBoundary as cast(cast(city_id as binary(4)) + 0x00000000 as bigint),
 city_RightBoundary as cast(cast(city_id + 1 as binary(4)) + 0x00000000 as bigint),
 first_street int null,
 last_street int null,
 constraint PK_Cities primary key clustered (city_id)
);
 
create table dbo.Streets1
(
 street_id int identity not null,
 city_id int not null references dbo.Cities (city_id),
 street_Name varchar(100) not null,
 constraint PK_Streets1 primary key clustered (street_id)
);
 
create table dbo.Streets2
(
 street_id int identity not null,
 city_id int not null references dbo.Cities (city_id),
 street_Name varchar(100) not null,
 constraint PK_Streets2 primary key clustered (street_id)
);
 
create table dbo.Streets3
(
 street_id int identity not null,
 city_id int not null references dbo.Cities (city_id),
 street_Name varchar(100) not null
);
 
create table dbo.Streets4
(
 row_id int identity not null,
 city_id int not null references dbo.Cities (city_id),
 street_Name varchar(100) not null,
 street_id as (cast(city_id as binary(4)) + 0x00000000) | cast(row_id as bigint) persisted not null,
 constraint PK_Streets4 primary key clustered (street_id)
);
 
insert into dbo.Cities
 (city_id, city_Name)
values
 (1, 'Город1'),
 (2, 'Город2'),
 (3, 'Город3'),
 (4, 'Город4');
 
insert into dbo.Streets1
 (city_id, street_Name)
 select
  t.city_id, t.street_Name
 from
  (
   select top(5000000)
    cast(rand(checksum(newid())) * 4 as int) + 1,
    cast(newid() as varchar(36))
   from
    master.dbo.spt_values a cross join
    master.dbo.spt_values b
  ) t(city_id, street_Name)
 order by
  newid();
 
update c
 set
  first_street = t.first_street,
  last_street = t.last_street
from
 (select city_id, min(street_id), max(street_id) from dbo.Streets1 group by city_id) t(city_id, first_street, last_street) join
 dbo.Cities c on c.city_id = t.city_id;
go
 
--alter table dbo.Streets1 add constraint PK_Streets1 primary key clustered (street_id);
 
set identity_insert dbo.Streets2 on;
insert into dbo.Streets2 (street_id, city_id, street_Name) select street_id, city_id, street_Name from dbo.Streets1;
set identity_insert dbo.Streets2 off;
 
set identity_insert dbo.Streets3 on;
insert into dbo.Streets3 (street_id, city_id, street_Name) select street_id, city_id, street_Name from dbo.Streets1;
set identity_insert dbo.Streets3 off;
 
set identity_insert dbo.Streets4 on;
insert into dbo.Streets4 (row_id, city_id, street_Name) select street_id, city_id, street_Name from dbo.Streets1;
set identity_insert dbo.Streets4 off;
 
create index IX_Street2__city_id on dbo.Streets2(city_id);
 
create unique clustered index IX_Streets3__city_id__street_id on dbo.Streets3 (city_id, street_id);
alter table dbo.Streets3 add constraint PK_Streets primary key nonclustered (street_id);
go
 
select * from dbo.Cities;
go
 
declare @s varchar(100), @city_id int = 1, @show_plan bit = 0, @show_io bit = 1;
 
if @show_plan = 1
 set statistics xml on;
if @show_io = 1
 set statistics io on;
set statistics time on;
 
/*
 Случай 1 - индекса по city_id в Streets нету.
 Поэтому будет применено сканирование диапазона кластерного индекса от first_street до last_street
*/
select
 @s = s.street_Name
from
 dbo.Cities c join
 dbo.Streets1 s on s.city_id = c.city_id and s.street_id between c.first_street and c.last_street
where
 c.city_id = @city_id
option
 (maxdop 1);
 
/*
 Случай 2 - индекс по city_id в Streets есть.
 Оптимизатор отказался от его использования, потому что сканирование диапазона кластерного индекса дешевле, чем сканирование диапазона индекса по city_id с последующим вытаскиванием значений street_Name из таблицы.
 В результате план выполнения аналогичен Случаю 1.
*/
select
 @s = s.street_Name
from
 dbo.Cities c join
 dbo.Streets2 s on s.city_id = c.city_id and s.street_id between c.first_street and c.last_street
where
 c.city_id = @city_id
option
 (maxdop 1);
 
/*
Аналогично Случаю 2
Показано как при наличии индекса по city_id, можно обойтись без first_street и last_street
*/
select
 @s = s.street_Name
from
 dbo.Cities c cross apply
 (select min(street_id), max(street_id) from dbo.Streets2 where city_id = c.city_id) d(first_street, last_street) join
 dbo.Streets2 s on s.city_id = c.city_id and s.street_id between d.first_street and d.last_street
where
 c.city_id = @city_id
option
 (maxdop 1);
 
/*
 Случай 4 - кластерный индекс по city_id, street_id. ПК некластерный по street_id
*/
select
 @s = s.street_Name
from
 dbo.Cities c join
 dbo.Streets3 s on s.city_id = c.city_id
where
 c.city_id = @city_id
option
 (maxdop 1);
 
/*
 Случай 5 - кластерный индекс по комбинированному столбцу из city_id и street_id
 Почти как Случай 4, но позволяет эффективно искать по ПК
*/
select
 @s = s.street_Name
from
 dbo.Cities c join
 dbo.Streets4 s on s.street_id >= c.city_LeftBoundary and s.street_id < c.city_RightBoundary
where
 c.city_id = @city_id
option
 (maxdop 1);
 
set statistics time off;
if @show_plan = 1
 set statistics xml off;
if @show_io = 1
 set statistics io off;
go
 
drop table dbo.Streets1, dbo.Streets2, dbo.Streets3, dbo.Streets4, dbo.Cities;
go
Выполнять лучше на 2016 или старше. Тогда, включив показ планов выполнения, можно будет увидеть сколько строк было прочитано на каком-либо шаге и сколько из них предано дальше.
1
 Аватар для Dinkin
783 / 556 / 136
Регистрация: 31.05.2013
Сообщений: 3,145
Записей в блоге: 3
10.06.2018, 22:54  [ТС]
invm, Ого,спасибо, за такой развернутый ответ. Буду разбираться.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
10.06.2018, 22:54
Помогаю со студенческими работами здесь

Исправьте немного кода для триггера
Имеются 2 таблицы: 1) Товары_на_складе(ID_склада, Наименование, Цена, Количество) 2) Товары_в_заказе(ID_заказа, Наименование, Цена,...

Немного теории
Доброго дня, форумчане! Пишу курсач на тему Системы программирования. Препод сказал, что у меня нет информации о видах систем...

Немного теории
Здравствуйте, ребята! Такой вопрос: У меня есть свой сайт. На нем я хочу подключить снег. Для запуска снега используется функция да и...

Немного о теории
Впервые мне попалась такая постановка задачи: создать класс ru.qwerty.vova.ivan.Main , который имплементирует интерфейс...

Немного теории
хочу освоить немного openGL стал гуглить, сейчас в теме хочу прояснить для себя немного теорию. 1)glut - это просто &quot;обертка&quot;,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru