Вход | Регистрация


1С:Предприятие :: 1С:Предприятие 8 общая

Иногда SQL удивляет или немного о агрегатных функциях.

Иногда SQL удивляет или немного о агрегатных функциях.
Я
   H A D G E H O G s
 
18.11.18 - 19:53
Дня доброго.
Жизнь полна сюрпризов и стереотипов.
Когда-то давно, смотря на план запроса вида

Выбрать
Таблица.ПолеИндексированное как ПолеИдексированное,
Максимум(Таблица.ПолеНеиндексированное как ПолеНеидексированное,
Из Таблица
Где Таблица.ПолеИндексированное=&Отбор
Сгруппировать ПО Таблица.ПолеИндексированное

я увидел длительное время выполнения и 10000 чтений.
Ага, подумал я, операция Максимум() - опасна и ею лучше не грешить.
И сделал зарубку, красный код.

Сегодня у меня возникла ситуация выбрать Первую любую МаркуPDF417 для массива Справок Б. Эту задачу можно было решить либо выборкой одном запросом и группировкой СправокБ по Максимуму() марки, либо запросом в цикле и выбором 1 марки, собственно, вот:
ВЫБРАТЬ
    АСФСостоянияМарок.СправкаБ КАК СправкаБ,
    МАКСИМУМ(АСФСостоянияМарок.МаркаPDF417) КАК МаркаPDF417
ИЗ
    РегистрСведений.АСФСостоянияМарок КАК АСФСостоянияМарок
ГДЕ
    АСФСостоянияМарок.СправкаБ в (&МассивСправокБ)

СГРУППИРОВАТЬ ПО
    АСФСостоянияМарок.СправкаБ

либо вот в цикле
ВЫБРАТЬ ПЕРВЫЕ 1
    АСФСостоянияМарок.СправкаБ КАК СправкаБ,
    АСФСостоянияМарок.МаркаPDF417 КАК МаркаPDF417
ИЗ
    РегистрСведений.АСФСостоянияМарок КАК АСФСостоянияМарок
ГДЕ
    АСФСостоянияМарок.СправкаБ = &МассивСправокБ

И я в принципе, склонялся к 2 варианту, пока не прогнал 1-ый запрос в профайлере и был озадачен. Профайлер показал 1 строку считанных данных.
Было немного увидительно, даже процедурный кэш почистил, а потом понял, что Минимум и Максимум будут всегда выбираться для моего случая, так как СправкаБ идет первой в индексе, а Марка - 2ой, и индекс уже отсортирован по СправкаБ, Марка.

Однако, стройна теория, мой друг...
Если мы посмотрим структуру индекса, мы увидим, что он отсортирован по возрастанию, и, максимальные значения Марки болтаются где-то вдали от начальной ветки B+ дерева с искомой справкой Б.
Даже если мы заменим Максимум() на Минимум(), мы получим 1 чтение.
Если мы заменим Максимум() на Количество() или КоличествоРазличных() мы получим 19800 чтений, что логично.
Где я не прав?
 
 
   H A D G E H O G s
 
1 - 18.11.18 - 20:04
Все, вопрос снят.
   H A D G E H O G s
 
2 - 18.11.18 - 20:07
Алгоритм просто проползет до конца субдерева СправкиБ, не перебирая все ветви, а идя по пути в Максимум.
Таким образом, Минимум() использовать оптимальнее.

Если я не прав - ткните.
Нигде не нашел в Инете про это.
   v77
 
3 - 18.11.18 - 20:26
Я ничо не понял. Я подозреваю, что нужно условия делать и в условиях должны быть индексированные поля. Без условий группировка, максимум, минимум будут сканировать всю таблицу и хоть ты заиндексируйся. Да и деньги индексировать это плохо. Слишком их много в индексе.
   Sasha_H
 
4 - 18.11.18 - 23:49
Насчет Количество и КоличествоРазличные - это действительно логично! :)

А вот почему решил, что минимум более оптимальнее Максимум. Мне кажется это от сортировки индекса зависит!
   H A D G E H O G s
 
5 - 19.11.18 - 10:04
(4) Ну индекс в 1С сортируется по возрастанию колонок всегда.
   Остап Сулейманович
 
6 - 19.11.18 - 10:12
(2) Это о вреде индексирования упорядоченных множеств? Или где?

Так уже давно известно, что индексирование наиболее эффективно для множеств с упорядоченностью типа "белый шум" и наименее эффективно для полностью упорядоченных. За ваши марки не скажу. Но думаю, что они заносятся последовательно? По возрастанию номеров (или ключевого свойства)?
   Остап Сулейманович
 
7 - 19.11.18 - 10:14
+ (6) Просто нарисуйте двоичное дерево для упорядоченного списка. Получите дерево с одной ветвью. Обход дерева займет времени (теоретически. исключая аномалии реализации) столько же, сколько прямой перебор списка.
   Остап Сулейманович
 
8 - 19.11.18 - 10:22
+ (7) А вообще - поддержкой агрегатов ИМХО забота прикладного программиста. Поскольку СУБД может поддерживать "на лету" общепринятые агрегаты типа СУММА, МИНИМУМ, МАКСИМУМ... Поддержка агрегатов по выборкам - забота прикладного программиста.
Это конечно не к 1С. Здесь прикладной программист не имеет доступа к хранимкам...
   H A D G E H O G s
 
9 - 19.11.18 - 10:23
(6) Нет.
(7) Нет.
(8) Нет.
   H A D G E H O G s
 
10 - 19.11.18 - 10:24
(6) Постарайтесь прочитать ситуацию вдумчиво, не скатываясь к шаблонам в мозгу.
 
 Рекламное место пустует
   Остап Сулейманович
 
11 - 19.11.18 - 10:27
(9) Что "нет"? Вы курс теории БД через окно проходили?
   H A D G E H O G s
 
12 - 19.11.18 - 10:29
(11) Я его вообще не проходил
   IVT_2009
 
13 - 19.11.18 - 10:30
Вопрос больше по теме алкоголя. Зачем вам первая марка для справки Б ?
   H A D G E H O G s
 
14 - 19.11.18 - 10:30
(13) Определить типмарок для справки Б (нетмарок, стараямарка68, новаямарка150)
   H A D G E H O G s
 
15 - 19.11.18 - 10:32
(11) Вопрос - почему и для функции Минимум() и для функции Максимум() - количество чтений=1. Проход по дереву индекса SQL не считает за чтение?
   H A D G E H O G s
 
16 - 19.11.18 - 10:34
(11) СправкаБ, для которой я выполняю замеры не лежит в середине списка, тоесть, мы не напарываемся на нее в корне b+ дерева и должны его пройти, вряд ли все прошедшие ветви лежат в одной странице данных SQL. Есть ли возможность узнать, какие страницы данных считывались?
   Остап Сулейманович
 
17 - 19.11.18 - 10:45
(15) Точно сказать тяжело. Нужно иметь доступ к БД. Но то что видно с первого взгляда :
Пример 1. - Выборка не из источника данных. А из одноэсной таблицы. Потому чтений 1000.
Пример 2 (Максимум) и 2 (Минимум) - выборка из регистра напрямую. И скорее всего агрегаты поддерживаются на уровне СУБД. Если это так - никто не ищет агрегат перебором. В БД указано место хранения минимума и максимума. Потому и нет разницы в количестве чтений.
   Остап Сулейманович
 
18 - 19.11.18 - 10:47
+ (17) Это как количество записей в таблице ДБФ. Хранится в заголовке. И чтобы взять reccount не нужно перебирать все записи. Аналогично прочие агрегаты.
   H A D G E H O G s
 
19 - 19.11.18 - 10:47
"В БД указано место хранения минимума и максимума."

Каким образом?
   Остап Сулейманович
 
20 - 19.11.18 - 10:50
(19) Аналогично количеству записей в таблице ДБФ.
   nicxxx
 
21 - 19.11.18 - 10:55
(5) Всегда ли? CREATE INDEX ind ON table (field1 DESC) нельзя разве написать?
   H A D G E H O G s
 
22 - 19.11.18 - 11:17
(20) Есть понимание, что Максимум марки для Справки1 и Максимум марки для Справки2 будут разные - как их хранить то?
   H A D G E H O G s
 
23 - 19.11.18 - 11:19
(21) Це не справжние индексы 1С.
   Кирпич
 
24 - 19.11.18 - 11:25
Так в B-дереве одинаково бежать что до самой большой, что до самой маленькой. Сразу с корня прыг и всё.
   H A D G E H O G s
 
25 - 19.11.18 - 11:27
(24) Корень B дерева начинается с середины диапазона. Так?
   H A D G E H O G s
 
26 - 19.11.18 - 11:30
(24) Попгрыгать придется не один раз. Сначало ища справку Б, которая у меня лежит ближе к концу диапазона, а потом ища Марку максимума(которая лежит в конце диапазона, а не в середине).
   H A D G E H O G s
 
27 - 19.11.18 - 11:38
(26) Вот и вопрос - почему прыжки не считаются за чтения?
Вернее, считаются за 1 чтение.
У меня прыжки по некластерному индексу, возможно, SQL в статистику профайлера не учитывает прыжки по индексу (само чтение данных IndexSeek), а учитывает только фактически считанные данные с точки зрения пользователя - сколько он строк таблицы прочитал ? Кто скажет?
   Кирпич
 
28 - 19.11.18 - 11:43
(27) фиг знает. смотря сколько записей наверное. может там всё на одной странице лежит
   Сияющий в темноте
 
29 - 19.11.18 - 11:44
Нормализованное дерево,так называемое раскрашенное,да минимум и максимум ищутся примерно одинаково.
Видимо,скуль вам пишет только обращение к данным,а индексы у него внутри и никто не хочет показывать,что у него там.
вообще,если все оптимально,то на первом листе индекса указан весь диапазон от минимума до максимума с делением,сколько влезло.
   H A D G E H O G s
 
30 - 19.11.18 - 11:51
(28) Порядка 100000.
   H A D G E H O G s
 
31 - 19.11.18 - 11:53
(29)
"Нормализованное дерево,так называемое раскрашенное,да минимум и максимум ищутся примерно одинаково. "
Полностью согласен, начинаем мы с примерно с середины диапазона, стоимость спуска до минимума и максимума примерно равны.

"Видимо,скуль вам пишет только обращение к данным,а индексы у него внутри и никто не хочет показывать,что у него там. "
Именно так я и предполагаю.
"если все оптимально,то на первом листе индекса указан весь диапазон от минимума до максимума с делением,сколько влезло."

Вот тут нифига не понял.
   Йохохо
 
32 - 19.11.18 - 12:13
лист с "Справка Б1, Б2" содержит ссылки на нижние листы с заголовками "Б1 пдф 1-1000, Б2 пдф 1-1000" "Б2 пдф 1001-2000"
каску нашел
   VS-1976
 
33 - 19.11.18 - 13:29
Нужно рассмотреть физически как состоит индекс, алгоритм поиска в составном индексе.

СправкаБ ( к примеру Б )
А
Б ----
В     |
      +
Таблица ссылок на данные
Ссылки на данные ( для oracle rowid )

Таблица ссылок индекса
Указатели в индексе МаркаPDF417 всех связанных со значением Б ( СправкаБ )

Таблица индекса МаркаPDF417 ( часть связанная с Б если небольшая в одном блоке то 1 чтение )

Так как в индекс может быть не перестроен, то в шапке предположительно могут быть данные количества записей всего ( включая удалённые ) тогда поиск макс или мин идёт сразу по индексу к примеру максимум Значение = МаркаPDF417[ 10 записей к примеру всего * N байт занимает 1 запись ( кортеж ) ]

Моё имхо
 
 
   Fram
 
34 - 20.11.18 - 00:07
(2) Только что потестил на таблице с 588 млн записей. Имеем строковую колонку varchar(510) и ascending некластерный индекс по ней. Всего около 2 млн различных значений.
MIN - 0.07 сек
MAX - 0.07 сек
Эти миллисекунды разве стоят заморочки? У твоей системы больше нет узких мест?
   Fram
 
35 - 20.11.18 - 00:12
ошибся немного - 5.5 млн различных значений
   H A D G E H O G s
 
36 - 20.11.18 - 00:13
(34) Заморочек стоит мое полное понимание происходящих процессов. Когда я их перестаю понимать - волнуюсь и покрываюсь мурашками.
   H A D G E H O G s
 
37 - 20.11.18 - 00:14
(34) Как посмотреть, сколько страниц индекса было считано?
   Fram
 
38 - 20.11.18 - 00:17
(34) поправочка эти миллисекунды похоже уходили на транспорт данных от сервера ко мне. когда сделал
select @s = min(
и
select @s = max(
даже наносекунлы не заняло
   Fram
 
39 - 20.11.18 - 00:20
хотя наносекунда может и была. SYSDATETIME() только 7 знаков после точки возращает :)
   rphosts
 
40 - 20.11.18 - 02:46
(2) эээ, индекс - сбалансированное б-дерево, что минимум что максимум должно быть примерно одинаково
   Провинциальный 1сник
 
41 - 20.11.18 - 07:29
(7) А с чего вы взяли, что СУБД не выполняет эвристическую балансировку дерева при создании? Добавление в порядке последовательного возрастания - весьма частый случай, и логично, что СУБД должна это предусматривать.
   los_hooliganos
 
42 - 20.11.18 - 08:10
(36) Мурашки это от раздражения периферических нервов. Попейте успокоительного.


Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Рекламное место пустует