Имя: Пароль:
1C
1С v8
Временные таблицы и индексы в запросах
,
0 Darklight
 
21.08.13
11:33
Видел в типовом коде (ЗУП) подобные конструкции запросов:

Выбрать
какой-то набор полей
поместить втНеСутьВажноКакойПромежуточныйНаборДанных
из какойтоисточник

;

Выбрать
вт.полеОтбора как ЗначениеОтбора
поместить втСписокОтбора
из втНеСутьВажноКакойПромежуточныйНаборДанных как вт
индексировать по
ЗначениеОтбора

;

Выбрать
ещё какой-то набор полей
из какойтоисточникЕщёОдин как данные

где
данные.КакоеТоПоле В (
выбрать
ЗначениеОтбора
из
втСписокОтбора
)

При этом данные.КакоеТоПоле - не индексированное поле!
Временная таблица втСписокОтбора используется лишь 1-2 раза внутри пакетного запроса.
и вот, собственно вопрос - насколько эффективна такая конструкция (я имею в виду оператор В и предварительное индексирование временной таблицы втСписокОтбора (разве на внутренней выборке внутри В индекс не будет потерян)?

и не эффективнее ли было использовать ВНУТРЕННЕЕ СОЕДИНЕНИЕ для таблицы втСписокОтбора (причём такой поход в ЗУП тоже используется и  в тех же пакетных запросах)

Изменится ли как-нибудь ответ, если  запросы будут с составным набором полей


Выбрать
какой-то набор полей
поместить втНеСутьВажноКакойПромежуточныйНаборДанных
из какойтоисточник

;

Выбрать
вт.полеОтбора1 как ЗначениеОтбора1,
вт.полеОтбора2 как ЗначениеОтбора2,
вт.полеОтбора3 как ЗначениеОтбора3,
вт.полеОтбора4 как ЗначениеОтбора4
поместить втСписокОтбора
из втНеСутьВажноКакойПромежуточныйНаборДанных как вт
индексировать по
ЗначениеОтбора1,
ЗначениеОтбора2

;

Выбрать
ещё какой-то набор полей
из какойтоисточникЕщёОдин как данные

где
(данные.КакоеТоПоле1, данные.КакоеТоПоле2, данные.КакоеТоПоле3, данные.КакоеТоПол4) В (
выбрать
ЗначениеОтбора1,
ЗначениеОтбора2,
ЗначениеОтбора3,
ЗначениеОтбора4
из
втСписокОтбора
)
2 viktor_vv
 
21.08.13
11:44
(1) ты уже тут чушь решил нести.

Индексировать ПО - это как раз и есть индексирование созданной временной таблицы БД.

А что ты имеешь ввиду под "а индексирование попавшего в отбор для дальнейшего использования" одному астралу известно.
3 viktor_vv
 
21.08.13
11:45
По поводу вот этого

(данные.КакоеТоПоле1, данные.КакоеТоПоле2, данные.КакоеТоПоле3, данные.КакоеТоПол4) В (
выбрать
ЗначениеОтбора1,
ЗначениеОтбора2,
ЗначениеОтбора3,
ЗначениеОтбора4
из
втСписокОтбора
)

на мой взгляд эффективнее будет внутреннее соединение.
Тут человек сравнивал, ближе к концу первой страницы.

v8: Оператор "ИЛИ", конструкция "ВЫБОР" и вероятность фуллскана при них
4 Fragster
 
модератор
21.08.13
11:50
(3) есть нюанс
5 Fragster
 
модератор
21.08.13
11:51
(0) внутреннее соединение может приводить к "задвоению", если заранее не побеспокоиться
6 viktor_vv
 
21.08.13
11:52
(5) Согласен.
7 H A D G E H O G s
 
21.08.13
11:53
(5) "задвоению"

Че это? Дубляж строк? Это мы осилим.

А так - да, "ВНУТРЕННЕ" лучше использовать, чем "В".
9 viktor_vv
 
21.08.13
12:04
(8) ну давай рассказывай, что ты имел ввиду под

"а индексирование попавшего в отбор для дальнейшего использования" ?

и что понимаешь под "попавшего в отбор" , физически как хранится этот твой, так называемый отбор ?
10 H A D G E H O G s
 
21.08.13
12:06
(9) Вряд ли ты что от него добьешься.
11 Darklight
 
21.08.13
12:14
(0)Забыл добавить  дирепктиву "РАЗЛМЧНЫЕ" при формировании временной таблтцы втСписокОтбора - для внутрннено соединения (5) это очень важно, для оператора "В" - только оптимизация. Так что будем считать что мы заранее побеспокоились об этом и говорим лишь о производительности.
(3)Спасибо за линк про ещё одно обсуждение вреда ИЛИ - почитаю.
(1)Я тут не суть индкексирования таблиц обсуждаю - а реальную пользу от этих индексов в определённых конструкциях запросов.
Расширя свой вопрос можно его дополнить так:
Если таблица втСписокОтбора  - это не временная таблица, а реальная таблица ИБ, у которой указанное поле(я) проиндекированы в БД (допустим это измерения регистра с установленным параметров "Индексировать") - по сути от этого ведь ответ не изменится! Или изменится?
12 Darklight
 
21.08.13
12:18
(7)Давайте попробуем уточнить одну важную деталь, которую я хочу понять - при указанном использовании оператор "В" - индекс по полю(ям) втСписокОтбора даёт ли какое-то преимущество и вообще используется ли?
То, что он дат положительный эффект в конструкции "ВНУТРЕННЕЕ СОЕДИНЕНИЕ" - это факт, мы не обсуждаем его наличие.
13 Ёпрст
 
21.08.13
12:20
(12) посмотри в плане запроса, во что твой "В" превращается.. усё станет понятней.
14 viktor_vv
 
21.08.13
12:22
(11) Тут есть нюанс "допустим это измерения регистра с установленным параметров "Индексировать")".

Установленный признак "Индексировать" для обычной таблицы создает дополнительный отдельный индекс по этому полю. Соотвественно для двух измерений с признаком "Индексировать" создаются два отдельных индекса, поэтому при внутреннем соединении по этим нескольким полям индексы могут не использоваться.

И у меня у самого попутно вопрос возник. При использовании Индексировать По для временной таблицы при указании нескольких полей, создается один составной индекс ?
15 Fragster
 
модератор
21.08.13
12:30
запилил замер - в справочнике ~160к записей, отбор по 5% случайных из них. пока выполняется.
16 Darklight
 
21.08.13
12:35
(15)ОФТОП, ради любопытства - а как Вы отбирает именно 5% элементов справочника в запросе?
Надеюсь это не банальное: "ну я заранее посчитал сколько 5% будет в шутках от всего числа элементов и поставил это значение в директиве "ПЕРВЫЕ"! Что кстати не даёт в общем смысле "случайные" записи - и повторный запуск с почти 100% вероятностью вернёт тот же набор (или очень близкий к нему).
17 Fragster
 
модератор
21.08.13
12:37
Запрос = Новый Запрос;
Запрос.Текст =
"
|ВЫБРАТЬ
|    КОЛИЧЕСТВО(*) КАК КоличествоКонтрагентов
|ИЗ
|    Справочник.Контрагенты КАК Контрагенты";
Выборка = Запрос.Выполнить().Выбрать();
Выборка.Следующий();
КоличествоКонтрагентов = Выборка.КоличествоКонтрагентов;
КоличествоОтбора = Цел(КоличествоКонтрагентов / 20);
Сообщить(КоличествоКонтрагентов);
Повторений = 100;

ГСЧ = Новый ГенераторСлучайныхЧисел;
Если Ложь Тогда
    МассивСсылок = Новый Массив;
    ТаблицаСсылок = Новый ТаблицаЗначений;
    ТаблицаСсылок.Колонки.Добавить("Ссылка", Новый ОписаниеТипов("СправочникСсылка.Контрагенты"));
    Для Сч = 1 по КоличествоОтбора Цикл
        Если Сч % 100 = 0 Тогда
            Состояние("Заполнение параметров " + Сч + " из " + КоличествоОтбора);
        КонецЕсли;
        
        Запрос.Текст = "
        |ВЫБРАТЬ ПЕРВЫЕ 1
        |    Вложенный.Ссылка КАК Ссылка
        |ИЗ
        |    (ВЫБРАТЬ ПЕРВЫЕ "+XMLСтрока(ГСЧ.СлучайноеЧисло(1, КоличествоКонтрагентов))+"
        |        Контрагенты.Ссылка КАК Ссылка
        |    ИЗ
        |        Справочник.Контрагенты КАК Контрагенты
        |    
        |    УПОРЯДОЧИТЬ ПО
        |        Ссылка) КАК Вложенный
        |
        |УПОРЯДОЧИТЬ ПО
        |    Ссылка УБЫВ";
        //|    (ВЫБРАТЬ ПЕРВЫЕ "+XMLСтрока(ГСЧ.СлучайноеЧисло(1, КоличествоКонтрагентов))+"
        Выборка = Запрос.Выполнить().Выбрать();
        Выборка.Следующий();
        МассивСсылок.Добавить(Выборка.Ссылка);
        Стр = ТаблицаСсылок.Добавить();
        Стр.Ссылка = Выборка.Ссылка;
    КонецЦикла;
КонецЕсли;
ТекДата = ТекущаяДата();
Пока ТекДата = ТекущаяДата() Цикл КонецЦикла;

Запрос.Текст =
"
|ВЫБРАТЬ
|    Контрагенты.Ссылка
|ИЗ
|    Справочник.Контрагенты КАК Контрагенты
|ГДЕ
|    Контрагенты.Ссылка В(&МассивСсылок)";
Запрос.УстановитьПараметр("МассивСсылок", МассивСсылок);
Для Сч = 1 по Повторений Цикл
    Результат = Запрос.Выполнить();
КонецЦикла;
Сообщить("Отбор через массив: " + (ТекущаяДата() - ТекДата - 1));


ТекДата = ТекущаяДата();
Пока ТекДата = ТекущаяДата() Цикл КонецЦикла;

Запрос.Текст =
"
|ВЫБРАТЬ
|    ТаблицаСсылок.Ссылка
|ПОМЕСТИТЬ ТаблицаСсылок
|ИЗ
|    &ТаблицаСсылок КАК ТаблицаСсылок
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
|    Контрагенты.Ссылка
|ИЗ
|    Справочник.Контрагенты КАК Контрагенты
|        ВНУТРЕННЕЕ СОЕДИНЕНИЕ ТаблицаСсылок КАК ТаблицаСсылок
|        ПО Контрагенты.Ссылка = ТаблицаСсылок.Ссылка";
Запрос.УстановитьПараметр("ТаблицаСсылок", ТаблицаСсылок);
Для Сч = 1 по Повторений Цикл
    Результат = Запрос.Выполнить();
КонецЦикла;
Сообщить("Отбор через внутреннее соединение: " + (ТекущаяДата() - ТекДата - 1));

ТекДата = ТекущаяДата();
Пока ТекДата = ТекущаяДата() Цикл КонецЦикла;

Запрос.Текст =
"
|ВЫБРАТЬ
|    ТаблицаСсылок.Ссылка
|ПОМЕСТИТЬ ТаблицаСсылок
|ИЗ
|    &ТаблицаСсылок КАК ТаблицаСсылок
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
|    Контрагенты.Ссылка
|ИЗ
|    Справочник.Контрагенты КАК Контрагенты
|ГДЕ
|    Контрагенты.Ссылка В
|            (ВЫБРАТЬ
|                ТаблицаСсылок.Ссылка
|            ИЗ
|                ТаблицаСсылок)";
Запрос.УстановитьПараметр("ТаблицаСсылок", ТаблицаСсылок);
Для Сч = 1 по Повторений Цикл
    Результат = Запрос.Выполнить();
КонецЦикла;
Сообщить("Отбор через В: " + (ТекущаяДата() - ТекДата - 1));

ТекДата = ТекущаяДата();
Пока ТекДата = ТекущаяДата() Цикл КонецЦикла;

Запрос.Текст =
"
|ВЫБРАТЬ
|    ТаблицаСсылок.Ссылка
|ПОМЕСТИТЬ ТаблицаСсылок
|ИЗ
|    &ТаблицаСсылок КАК ТаблицаСсылок
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
|    Контрагенты.Ссылка
|ИЗ
|    Справочник.Контрагенты КАК Контрагенты
|ГДЕ
|    (Контрагенты.Ссылка, ИСТИНА) В
|            (ВЫБРАТЬ
|                ТаблицаСсылок.Ссылка,
|                ИСТИНА
|            ИЗ
|                ТаблицаСсылок)";
Запрос.УстановитьПараметр("ТаблицаСсылок", ТаблицаСсылок);
Для Сч = 1 по Повторений Цикл
    Результат = Запрос.Выполнить();
КонецЦикла;
Сообщить("Отбор через В (Exists): " + (ТекущаяДата() - ТекДата - 1));

ТекДата = ТекущаяДата();
Пока ТекДата = ТекущаяДата() Цикл КонецЦикла;

Запрос.Текст =
"
|ВЫБРАТЬ
|    ТаблицаСсылок.Ссылка КАК Ссылка
|ПОМЕСТИТЬ ТаблицаСсылок
|ИЗ
|    &ТаблицаСсылок КАК ТаблицаСсылок
|
|ИНДЕКСИРОВАТЬ ПО
|    Ссылка
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
|    Контрагенты.Ссылка
|ИЗ
|    Справочник.Контрагенты КАК Контрагенты
|        ВНУТРЕННЕЕ СОЕДИНЕНИЕ ТаблицаСсылок КАК ТаблицаСсылок
|        ПО Контрагенты.Ссылка = ТаблицаСсылок.Ссылка";
Запрос.УстановитьПараметр("ТаблицаСсылок", ТаблицаСсылок);
Для Сч = 1 по Повторений Цикл
    Результат = Запрос.Выполнить();
КонецЦикла;
Сообщить("Отбор через внутреннее соединение + индекс: " + (ТекущаяДата() - ТекДата - 1));

ТекДата = ТекущаяДата();
Пока ТекДата = ТекущаяДата() Цикл КонецЦикла;

Запрос.Текст =
"
|ВЫБРАТЬ
|    ТаблицаСсылок.Ссылка
|ПОМЕСТИТЬ ТаблицаСсылок
|ИЗ
|    &ТаблицаСсылок КАК ТаблицаСсылок
|
|ИНДЕКСИРОВАТЬ ПО
|    Ссылка
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
|    Контрагенты.Ссылка
|ИЗ
|    Справочник.Контрагенты КАК Контрагенты
|ГДЕ
|    Контрагенты.Ссылка В
|            (ВЫБРАТЬ
|                ТаблицаСсылок.Ссылка
|            ИЗ
|                ТаблицаСсылок)";
Запрос.УстановитьПараметр("ТаблицаСсылок", ТаблицаСсылок);
Для Сч = 1 по Повторений Цикл
    Результат = Запрос.Выполнить();
КонецЦикла;
Сообщить("Отбор через В + индекс: " + (ТекущаяДата() - ТекДата - 1));

ТекДата = ТекущаяДата();
Пока ТекДата = ТекущаяДата() Цикл КонецЦикла;

Запрос.Текст =
"
|ВЫБРАТЬ
|    ТаблицаСсылок.Ссылка
|ПОМЕСТИТЬ ТаблицаСсылок
|ИЗ
|    &ТаблицаСсылок КАК ТаблицаСсылок
|
|ИНДЕКСИРОВАТЬ ПО
|    Ссылка
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
|    Контрагенты.Ссылка
|ИЗ
|    Справочник.Контрагенты КАК Контрагенты
|ГДЕ
|    (Контрагенты.Ссылка, ИСТИНА) В
|            (ВЫБРАТЬ
|                ТаблицаСсылок.Ссылка,
|                ИСТИНА
|            ИЗ
|                ТаблицаСсылок)";
Запрос.УстановитьПараметр("ТаблицаСсылок", ТаблицаСсылок);
Для Сч = 1 по Повторений Цикл
    Результат = Запрос.Выполнить();
КонецЦикла;
Сообщить("Отбор через В (Exists) + индекс: " + (ТекущаяДата() - ТекДата - 1));
18 Fragster
 
модератор
21.08.13
12:37
результаты:
Отбор через массив: 91
Отбор через внутреннее соединение: 65
Отбор через В: 72
Отбор через В (Exists): 68
Отбор через внутреннее соединение + индекс: 71
Отбор через В + индекс: 69
Отбор через В (Exists) + индекс: 71
19 Darklight
 
21.08.13
12:37
(14)А как же кластерный индекс и его преимущества при  правильном следовании индексированных полей?
20 Fragster
 
модератор
21.08.13
12:42
(18)+ хотя в любом случае для каждой СУБД (и файловой, конечно) и каждого запроса нужно проводить отдельное тестирование, если не устраивает...
21 Fragster
 
модератор
21.08.13
12:43
вот тут недавно сняли режим совместимости - запрос с

Выразить(Таблица.Поле как Документ.Документ) = значение

перестал использовать индекс (в режиме совместимости 8.1 испоьлзовал)
22 Darklight
 
21.08.13
12:47
(17)О да, чувствуется фундаментальный подход. Да, у Вас уже есть соответствующие наработки. Круто.
23 Fragster
 
модератор
21.08.13
12:49
(22) если ложь = для первого запуска была истина, просто отбор заполняется долго, я его запомнил.
24 Darklight
 
21.08.13
12:52
(17)А для чего вот это

ТекДата = ТекущаяДата();
Пока ТекДата = ТекущаяДата() Цикл КонецЦикла;
25 Fragster
 
модератор
21.08.13
12:54
(24) ожидание начала секунды
26 Darklight
 
21.08.13
12:57
(18)Результат, скажем, неожиданный - индексы проиграли внутреннему соединению без индексов. А конструкция "В" с индексом выиграла у внутреннего соединения с индексом.
(25)Ладно, это понятно - для чистоты замеров.
Но У вас  выборка одна и та же - как же кеш. Или это как раз то, что нужно - понятно что кеш, разбираем производительность разных подходов когда данные априори берутся из кеша, какой подход их эффективнее от-туда возьмёт.
27 Darklight
 
21.08.13
13:01
(21)Да, удивительный это 1С.
Вот тоже недавно отлаживал оптимизацию одного запроса.
Так у меня  условие вида Поле Ссылка ТипСсылки работало значительно медленнее чем ВЫРАЗИТЬ(Поле КАК ТипСсылки) НЕ ЕСТЬ NULL
28 viktor_vv
 
21.08.13
13:01
Посмотрел планы запроса для

Select
id
From sc72
Where id in (select id from #tempkl)

и

Select
sc.id
From sc72 as sc
inner join #tempkl as t on t.id = sc.id

оба почти одинаковые, в конце inner join / nested loops

только для in дополнительно есть еще group by для #tempkl.

для id в #tempkl создан индекс.
29 Darklight
 
21.08.13
13:11
(28)судя по всему в операторе "В" всё же наличие индекса играет роль. Замеры в (18) тому подтверждение (думаю, что разница в 2 сек всё же погрешности и флукцтации самого SQL сервера).
Но вот, то что без индексов ВНУТРЕННЕЕ СОЕДИНЕНИЕ обогнало все тесты с индексом?
Хотя есть более простое объяснение всему этому - SQL просто забил на индекс при построении плана запроса и не использовал его. Поэтому все индексированные тесты прошли одинаково, и были медленнее ВНУТРЕННЕГО СОЕДИНЕНИЯ без индексов, т.к. уходило время  на создание индекса (правда, что уже очень много уходило  разница достаточно большая).

Думаю, что данный тест нужно прогнать в цикле раз 100 хотя бы (на каждой итерации свой случайный набор выборки; естественно замеры усредняются по каждому непосредственному тесту). Вот, тогда будет более правильный результат.
Да, и ещё, после основной выборки данных для отбора, я бы ещё 3 сделал таких же, но нигде далее не используемых - для сброса кеша и так прогнал бы ещё одну серию тестов для сравнения.
30 Fragster
 
модератор
21.08.13
13:12
(29) потому что создание индекса тожезанимает время
31 Fragster
 
модератор
21.08.13
13:13
для 1% записей:
Отбор через массив: 18
Отбор через внутреннее соединение: 12
Отбор через В: 13
Отбор через В (Exists): 13
Отбор через внутреннее соединение + индекс: 15
Отбор через В + индекс: 14
Отбор через В (Exists) + индекс: 14
32 Darklight
 
21.08.13
13:17
(31)Всё тоже самое, что и в (18)
33 Fragster
 
модератор
21.08.13
13:21
для 0,01% записей (1000 повторений):
Отбор через массив: 4
Отбор через внутреннее соединение: 16
Отбор через В: 15
Отбор через В (Exists): 19
Отбор через внутреннее соединение + индекс: 23
Отбор через В + индекс: 25
Отбор через В (Exists) + индекс: 25
34 Darklight
 
21.08.13
13:32
(33)Что так массив круто вырвался вперёд?
А индексы вообще отстали - ну тут то ясно дело, что затраты на индексирование небольших объёмов данных не оправданы.
35 Darklight
 
21.08.13
13:44
(17)Кстати, а есть вопросы к генератору случайной выборки отбора:
1. Не увидел фильтра на отсечение уже выбранных контрагентов (там же в несколько итераций это происходит) - т.е. весьма вероятны дубли - или это так и нужно?
2. И всё-таки сама выборка с использованием  директивы "ПЕРВЫЕ" (да ещё и с упорядоичванием) не такая уже и случайная получается, даже если инвертировать порядок.
Наверное, надо было генериь два случайный числа, и на их основе искать по коду контрагентов, отсекая сверху и снизу (правда они строковые - значит нужно использовать оператор "ПОДОБНЫЕ" - а это очень медленно).
36 viktor_vv
 
21.08.13
13:51
И кстатит в дополнение к (28) , там не всегда наличие индекса для таблицы условий играет роль.
В варианте (28) в таблице условия где-то 5% записей. Поле id основной таблицы sc72 индексированно. В плfне запроса получается index scan / table scan (зависит от наличия индекса) для меньшей таблицы, и index seek по основной таблице для каждой записи таблицы условия.
Я так подозреваю index scan от table scan особо не отличаются по скорости, разве что объемом чтения.
37 viktor_vv
 
21.08.13
13:54
(36)+ Поэтому в некоторых случаях можно и не индексировать временную таблицу, дабы время не терять, если для второй таблицы уже есть подходящий индекс.
38 Serginio1
 
21.08.13
13:56
(34) Запрос может кэшироваться. Поэтому нужно задавать различные параметры
39 viktor_vv
 
21.08.13
13:57
(37)+ отчасти это ответ на вопрос в (12)

"при указанном использовании оператор "В" - индекс по полю(ям) втСписокОтбора даёт ли какое-то преимущество и вообще используется ли"
40 ИС-2
 
naïve
21.08.13
14:07
если по простому, то индексировать надо по полям которые часто используются в связях?
Для 1000 документов есть смысл строить индекс?
41 Darklight
 
21.08.13
14:09
(39)Ок, кажется ясно
(40)Никакого смысла нет
42 viktor_vv
 
21.08.13
14:16
И опять же нюанс. Скорее всего это для внутреннего соединения по одному полю подходит. А вот если условие соедиенния по двум полям, то учитывая что для обычной таблицы в 1С нельзя задать произвольный составной индекс, то лучше временную проиндексировать по нескольким полям, тогда может быть быстрее table scan основной и поиск по индексу во временной.
43 Fragster
 
модератор
21.08.13
14:29
(35).1 да и пофиг
.2 дело именно в случайности количества. мы выбираем из 1,2,3,4,5 первые случайное количество (допустим, 3), получаем 1,2,3. сортируем по убыванию, получаем первые 1 - итого 3
44 Darklight
 
21.08.13
14:37
у меня небольшой справочник контрагентов (надо на регистре проводок по БУ попробовать - там много записей):
Количество всего 4 237 отобрано 847 повторений 1000

Отбор через массив: 83
Отбор через внутреннее соединение: 52
Отбор через В: 61
Отбор через В (Exists): 59
Отбор через внутреннее соединение + индекс: 65
Отбор через В + индекс: 72
Отбор через В (Exists) + индекс: 72

Количество всего 4 237 отобрано 84 повторений 10 000
Отбор через массив: 40
Отбор через внутреннее соединение: 153
Отбор через В: 164
Отбор через В (Exists): 158
Отбор через внутреннее соединение + индекс: 222
Отбор через В + индекс: 262
Отбор через В (Exists) + индекс: 280
45 viktor_vv
 
21.08.13
14:52
Ну оно и получается, что индексирование для временной таблицы таки особой роли не играет, даже немного замедляет. Это для использования ее в качестве ограничивающего условия.

Еще немного поэкспериментировал.
Для количества записей во временной таблице выше 10 % от основной, вместо nested loops используется merge join и для обеих таблиц index scan .
Если для временной таблицы не делать индексирование, то для нее table scan плюс дополнительно сортировка по полю условия.
Вот оценить что быстрее, создание индекса и затем index scan, или сортировка таблицы по полю без индекса не возьмусь.
Независимо от того, куда вы едете — это в гору и против ветра!