Нужен ли индекс, ЛЕВОЕ СОЕДИНЕНИЕ
Нужен ли индекс, ЛЕВОЕ СОЕДИНЕНИЕ ?
Первая таблица большая очень. 13 млн
Из неё поле (без индекса, одно из) соединяем со второй таблицей "маленькой" 100 тыс.записей
Во второй таблице поле соединения проиндексировано.
У меня не ВНУТРЕЕНЕЕ СОЕДИНЕНИЕ, а Левое соединение.
Нужно ли добавлять индекс на поле соединения первой таблицы?
Первая таблица большая очень. 13 млн
Из неё поле (без индекса, одно из) соединяем со второй таблицей "маленькой" 100 тыс.записей
Во второй таблице поле соединения проиндексировано.
У меня не ВНУТРЕЕНЕЕ СОЕДИНЕНИЕ, а Левое соединение.
Нужно ли добавлять индекс на поле соединения первой таблицы?
По теме из базы знаний
Ответы
Подписаться на ответы
Инфостарт бот
Сортировка:
Древо развёрнутое
Свернуть все
(1)
В моем представлении в этом случае база будет брать строку из 1-ой таблицы и искать во второй.
Следовательно индекс в первой таблице не нужен, во всяком случае, если вы не пытаетесь использовать это поле первой таблицы где-то еще, например, в условии ГДЕ, или сортировке.
Нужен ли индекс во-второй зависит от его селективности, а также является ли проиндексированное поле ведущем в индексе.
By the way, если речь идет о физической таблице, то она итак в 1С (всегда?) имеет кластерный индекс.
Нужно ли добавлять индекс на поле соединения первой таблицы?
В моем представлении в этом случае база будет брать строку из 1-ой таблицы и искать во второй.
Следовательно индекс в первой таблице не нужен, во всяком случае, если вы не пытаетесь использовать это поле первой таблицы где-то еще, например, в условии ГДЕ, или сортировке.
Нужен ли индекс во-второй зависит от его селективности, а также является ли проиндексированное поле ведущем в индексе.
By the way, если речь идет о физической таблице, то она итак в 1С (всегда?) имеет кластерный индекс.
(1) нужно. Если левая таблица по определению больше правой, то скорее всего оптимизатор будет соединять правую таблицу с левой внутренним соединением и добавит недостающие записи из левой.
Т.е. именно к меньшей таблице будет произведено соединение большей таблицы. Соответственно индекс в большей как правило настоятельно рекомендуется.
Т.е. именно к меньшей таблице будет произведено соединение большей таблицы. Соответственно индекс в большей как правило настоятельно рекомендуется.
а что за большая таблица? очень на регистр сведений похоже
так в нем измерения изначально как-то индексированы
как в документах и справочниках некоторые поля. ссылка, Дата, Код....)
так в нем измерения изначально как-то индексированы
как в документах и справочниках некоторые поля. ссылка, Дата, Код....)
Ну а как делается соединение? Есть несколько способов у скула.
1. Выбрать все строки первой таблицы и найти для каждой из них строку во второй таблице.
1.0. нужно понимать, что если в исходной таблице у нас 13кк записей, то все эти строки будут выбраны, отсюда:
1.0.1. Если во второй таблице есть индекс, то для каждой строки второй таблицы будет произведено log 2(N) "чтений". В действительности, мы прочитаем индекс фактически весь и сразу, т.к. на все 13кк первой таблицы должна найтись строка во второй. Это называется NESTED LOOP. Но по индексу. Т.е. это быстрый поиск в цикле.
1.0.2. Если во второй таблице индекса нет, то мы можем попробовать соединить строки методом HASH JOIN. Для этого скул строит по соединяемым колонкам unorderedmap - соответствие. В идеальном случае в нем поиск отрабатывает за O(1), т.е. "сразу". Но идеальные случаи часто бывают в сказках, а в реальной жизни происходят коллизии, когда два и более значения оказываются с одинаковым HASH. Чем больше значений в списке, тем больше коллизий.
Т.е. у нас по первой таблице производится построение unorderedmap - 13кк значений. Потом по второй таблице строится unorderedmap, потом уже для всех значений первой таблицы ищутся все значения второй. Ну тут от значений все зависит прямо.
1.0.3. Если в обоих таблицах есть индекс, то это однопроходной скан индекса. M + N.
1.1. У нас может быть наложен еще какой-то отбор на поля первой таблицы, чтобы не выбирать все 13кк значений.
1.1.1. Есть индекс на фильтр?
1.1.2. Нет индекса на фильтр?
...
Индекс - это упорядоченный по полям массив, в котором эти поля дополнительно лежат. Типа ["А","Б","В",...]. По индексу можно хорошо соединяться. Если в обоих таблица есть индекс, то соединение происходит за M + N чтений. Если только во второй таблице, то M * Log 2(N). HASH JOIN требует построения массива для двух таблиц, а это уже больше M + N, т.к. расчет хеш-функции не является бесплатным, плюс коллизии.
1. Выбрать все строки первой таблицы и найти для каждой из них строку во второй таблице.
1.0. нужно понимать, что если в исходной таблице у нас 13кк записей, то все эти строки будут выбраны, отсюда:
1.0.1. Если во второй таблице есть индекс, то для каждой строки второй таблицы будет произведено log 2(N) "чтений". В действительности, мы прочитаем индекс фактически весь и сразу, т.к. на все 13кк первой таблицы должна найтись строка во второй. Это называется NESTED LOOP. Но по индексу. Т.е. это быстрый поиск в цикле.
1.0.2. Если во второй таблице индекса нет, то мы можем попробовать соединить строки методом HASH JOIN. Для этого скул строит по соединяемым колонкам unorderedmap - соответствие. В идеальном случае в нем поиск отрабатывает за O(1), т.е. "сразу". Но идеальные случаи часто бывают в сказках, а в реальной жизни происходят коллизии, когда два и более значения оказываются с одинаковым HASH. Чем больше значений в списке, тем больше коллизий.
Т.е. у нас по первой таблице производится построение unorderedmap - 13кк значений. Потом по второй таблице строится unorderedmap, потом уже для всех значений первой таблицы ищутся все значения второй. Ну тут от значений все зависит прямо.
1.0.3. Если в обоих таблицах есть индекс, то это однопроходной скан индекса. M + N.
1.1. У нас может быть наложен еще какой-то отбор на поля первой таблицы, чтобы не выбирать все 13кк значений.
1.1.1. Есть индекс на фильтр?
1.1.2. Нет индекса на фильтр?
...
Индекс - это упорядоченный по полям массив, в котором эти поля дополнительно лежат. Типа ["А","Б","В",...]. По индексу можно хорошо соединяться. Если в обоих таблица есть индекс, то соединение происходит за M + N чтений. Если только во второй таблице, то M * Log 2(N). HASH JOIN требует построения массива для двух таблиц, а это уже больше M + N, т.к. расчет хеш-функции не является бесплатным, плюс коллизии.
(8) Шансы того, что скл сервер выберет nested loop при джойне 13kk записей, весьма малы. Разве что там TOP будет в запросе или это подзапрос в EXISTS, например. Скорее всего просто построит хэши по меньшей таблице и прогонит через них большую. В постгресе, подозреваю, примерно так же будет, но голову на отсечение не дам
(9)
Шансы того, что скл сервер выберет nested loop при джойне 13kk записей
Там смотрятся две таблицы. 13кк + 100к в любом случае уже есть, если нет доп.фильтров, попадающих в индекс. И log 2(100к) = 16,3 где-то, т.е. 13кк х 16,3к : 2 -> эффективность NESTED LOOP. Для 13кк хеш-таблицу строить скул вполне может выбрать, но он строит ее по меньшей таблице. И если у нас поля соединения - это уникальные поля (ссылка, например), то будет много сбрасываний на диск при построении хеша большой таблицы. По крайней мере так пишет . Остается понять, что для скула в данном случае маленькая таблица, что средняя и что большая.
(10)
В пятничный вечер я уже не особо могу в эти расчёты вникнуть, но точно знаю, что оптимизатор считать будет совсем не так. И при таких вводных данных для сферического левого джойна в вакууме без дополнительных условий вероятность увидеть nested loop стремится к нулю. При индексе на соотв. поле на таблице 13кк возможен еще вариант мердж-джойном.
(10)
Я вроде так и написал - хэш таблица на меньшей и по ней прогонит большую.
(10)
При раскладе 13кк vs 100к вроде очевидно
13кк + 100к в любом случае уже есть, если нет доп.фильтров, попадающих в индекс. И log 2(100к) = 16,3 где-то, т.е. 13кк х 16,3к : 2 -> эффективность NESTED LOOP.
В пятничный вечер я уже не особо могу в эти расчёты вникнуть, но точно знаю, что оптимизатор считать будет совсем не так. И при таких вводных данных для сферического левого джойна в вакууме без дополнительных условий вероятность увидеть nested loop стремится к нулю. При индексе на соотв. поле на таблице 13кк возможен еще вариант мердж-джойном.
(10)
Для 13кк хеш-таблицу строить скул вполне может выбрать, но он строит ее по меньшей таблице.
Я вроде так и написал - хэш таблица на меньшей и по ней прогонит большую.
(10)
Остается понять, что для скула в данном случае маленькая таблица, что средняя и что большая.
При раскладе 13кк vs 100к вроде очевидно
Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот