Что быстрее по производительности в запросе ВРЕМЕННАЯ ТАБЛИЦА или СОЕДИНЕНИЕ

1. timeforlive 16 19.02.25 16:24 Сейчас в теме
Всем привет.
Не могу проверить нормально производительность запроса. Стало интересно какой запрос 1С (8.3.22) быстрее отработает на MS SQL на больших размерах таблиц (свыше миллиона записей в каждой таблице)? Либо они одинакого отработают по времени (запросы ниже).

Вариант-1:
Временная таблица с отбором по ссылке. Потом соединение с временной таблицей.

    ВЫБРАТЬ
    Т1.Ссылка КАК Ссылка
    ПОМЕСТИТЬ ВТ
    ИЗ
    Документ.КакойТоДокументМиллионЗаписей КАК Т1
    ГДЕ
    Т1.Ссылка = &Ссылка

    ;
    ВЫБРАТЬ
    Т1.Ссылка КАК Ссылка
    ИЗ
    ВТ КАК Т1
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КакойТоРегистрМиллоинЗаписей КАК Т2
    ПО Т1.Ссылка = Т2.СсылкаНаДокумент
Показать


Вариант-2:
Соединение двух таблиц, потом отбор по ссылке.

ВЫБРАТЬ
Т1.Ссылка КАК Ссылка
ИЗ
Документ.КакойТоДокументМиллионЗаписей КАК Т1
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КакойТоРегистрМиллоинЗаписей КАК Т2
ПО Т1.Ссылка = Т2.СсылкаНаДокумент

ГДЕ
Т1.Ссылка = &Ссылка


Известно, что MS SQL сначала выполняет конструкцию "ИЗ", потом "СОЕДИНЕНИЕ", потом "ГДЕ" и т.д.
Будет ли план запроса в Варианте-2 сначала соединять все записи обеих таблиц между собой, а потом накладывать отбор?
У меня время выполнения запроса почти одинаковое время показывает на реальных данных (десятки секунд) для обоих вариантов.
У регистра не индексируемое поле.
По теме из базы знаний
Вознаграждение за ответ
Показать полностью
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. nomad_irk 81 19.02.25 16:30 Сейчас в теме
(1) нагенерить по 1М записей в 2 таблицы - невыполнимая задача для вас?
Теория говорит о том, что отборы в ГДЕ работают уже после соединения таблиц.
4. starik-2005 3167 19.02.25 16:37 Сейчас в теме
(2)
Теория говорит о том
Ужасная теория, отставшая от жизни )))
5. Sashares 33 19.02.25 16:43 Сейчас в теме
(4) https://infostart.ru/1c/articles/527529/
Соединение таблиц VS. Проверка условия ГДЕ

Комментарий. Сначала выполняется Соединение таблиц. Об этом написано в учебниках SQL. Поэтому перед соединением необходимо тщательно подготовить таблицы: убрать «ненужные» записи, подключить индексы. Контрпример на сравнение очередности "Соединение таблиц" - "Проверка условия ГДЕ" пока не придумал.
11. redfred 19.02.25 19:34 Сейчас в теме
(5) Это логический порядок, физический может отличаться. Оптимизатор вполне может фильтрацию пропихнуть поближе к чтению данных, до соединения
13. Sashares 33 19.02.25 20:33 Сейчас в теме
(11) Но ведь может и не пропихнуть.
Так зачем добавлять проблем там, где можно не добавлять.
14. redfred 19.02.25 20:51 Сейчас в теме
(13) Может и не пропихнуть. Поэтому всегда нужно смотреть планы, а не гадать.
19. starik-2005 3167 20.02.25 13:40 Сейчас в теме
(13) Там фильтр в ГДЕ относится к первой таблице. Так что в любом случае в современных реалиях первая таблица будет отобрана по фильтру до соединения, раз фильтр - это уникальный индекс (не может быть две одинаковые ссылки в одной таблице). Она и будет потом искаться в таблице второй.
9. SlavaKron 19.02.25 17:45 Сейчас в теме
(1)
время выполнения запроса почти одинаковое
Вы сами ответили на свой вопрос. Очевидно, что ms sql сначала прикидывает, что эффективнее сделать: соединение или отбор, ведь отбор для основой таблицы при левом соединении равносилен условию в соединении.
В первом случае тратится время на создание ВТ, во втором - время на "прикидывание".
12. spacecraft 19.02.25 20:11 Сейчас в теме +0.1 $m
(1) второй вариант.
Оптимизатор отработает правильно.
Приблизительно такой план выполнения запроса получится:
Fields:(
    T1._IDRRef,
    T2._Fld31105,
    T2._Fld31106
)
_REFERENCE188 (T1) RANGE SCAN USING INDEX (_REFERENCE188_S_HPK@) (2 fields)
WHERE
        (T1._IDRRef = 80290015E9B8C48D11E2CDED714AB055)
NESTED OUTER LOOP
_INFORG31103 (T2) RANGE SCAN USING INDEX (_INFORG31103_1@) (4 fields)
WHERE
        (08 = T2._Fld31104_TYPE)
        AND
        (000000BC = T2._Fld31104_RTRef)
        AND
        (T1._IDRRef = T2._Fld31104_RRRef)
Показать
15. -AI- 20.02.25 11:47 Сейчас в теме
(1) с временной таблицей будет точно быстрее,
если её данные будут использоваться несколько раз
17. paulwist 20.02.25 12:05 Сейчас в теме
(1)
У меня время выполнения запроса почти одинаковое время показывает на реальных данных (десятки секунд) для обоих вариантов.


Планы в xml-формате в студию для обоих вариантов.

Всё остальное разговор про "сферического коня." :)
3. starik-2005 3167 19.02.25 16:31 Сейчас в теме
Ну так а голова на что?

Какую задачу решаем? Простую - прочитать данные из таблиц, т.е. из файла, из страниц в этом файле. Чем меньше прочитаем - тем лучше. В обоих случаях читаем одно и то же, если не затупит оптимизатор.

Отсюда очевидно, что читать надо соединяемые таблицы минимально, по индексам.

Отсюда очевидно, что в первом случае мы читаем одну строчку таблицы и кладем ее во временную таблицу, потом читаем все строчки из второй таблицы, которые соответствуют условию связи. Если у нас есть индекс на эту связь, то мы читаем оттуда только индекс, а по нему уже только те строчки, которые равны. Если индекса нет, то мы читаем все строчки второй таблицы, а дальше оставляем только те, которые соответсвуют условию.

Во втором случае мы читаем ту же одну строчку из первой таблицы и те же строчки из второй. И тоже все упирается в индекс.

Т.е. в конкретно этом случае нет вот вообще никакой разницы, ну кроме того, что в первом случае ты больше пишешь слов.

ЗЫ: вообще, тут очевидно, что лучше вообще первую таблицу не читать: "выбрать чтото из регистр где документссылка = &ссылка"
6. Said-We 19.02.25 16:47 Сейчас в теме
(1) Для конкретно задачи из {1} быстрее будет третий вариант:
ВЫБРАТЬ
Т.СсылкаНаДокумент КАК Ссылка
ИЗ
 РегистрСведений.КакойТоРегистрМиллоинЗаписей КАК Т
ГДЕ Т.СсылкаНаДокумент = &Ссылка
7. Sashares 33 19.02.25 16:48 Сейчас в теме
(6)
В данном случае быстрее будет не выполнять запрос, потому что ссылка уже известна.
-AI-; nomad_irk; +2 Ответить
8. Said-We 19.02.25 16:50 Сейчас в теме
(7) Нужны же записи из РС. Их может быть много или не быть. Понятно, что третий вариант при отсутствии записей в РС даст другой результат, но думаю это не сильно принципиально...
10. e9504100606 94 19.02.25 19:21 Сейчас в теме
(6) если в регистре нет этого документа, то запрос вернется пустой. Пример на сайте курсы-рф:
курсы-по-1с. рф/бесплатное/2019-12-24-about-the-difference-in-conditions-in-the-join-tables

P.S. почему-то ссылка нормально не копируется с доменом .рф
16. Said-We 20.02.25 11:54 Сейчас в теме +0.1 $m
(15) Если временная таблица будет занимать места в несколько гигов, то быстрее точно не будет. И память кончится быстро. :-)
SQL ещё и статистику использует, сначала один план запроса выполняется, а со временем на тех же данных запрос может выполняться уже иначе. Хотя данные могли сильно не меняться.
18. -AI- 20.02.25 13:17 Сейчас в теме
(16)
Если временная таблица будет занимать места в несколько гигов, то быстрее точно не будет. И память кончится быстро. :-)
так и знал, что надо добавить, что данных в ней должно быть немного...
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот