Имя: Пароль:
1C
1C 7.7
v7: маленький SQL-эксперимент
0 ADirks
 
19.11.13
12:27
Оказывается, задавать условие константной строкой прямо в тексте запроса выгоднее, чем через временную таблицу.
Экспериментировал на 2005, 10000 значений
соотношение 42 / 58  в пользу константного списка, и это не учитывая времени на создание таблички - чистое время SELECT'ов.

Самое большое время в этом тесте ушло на формирование текста запроса :)


Собственно, эксперимент:
Процедура ДлинныйСписок()
    стр = ""; зпт = "";
    Для н = 1 По 10000 Цикл
        //стр = стр + зпт + н;
        стр = стр + зпт + н;
        зпт = ",";
    КонецЦикла;

    ЗапросСКЛ.Выполнить("
    |create table #t1(к1 int)
    |declare @k1 int
    |set @k1 = 1
    |while @k1 <= 10000
    |begin
    |    insert into #t1 values (@k1)
    |    set @k1 = @k1 + 1
    |end
    |
    |");
    
    тз = ЗапросСКЛ.ВыполнитьИнструкцию("Set NoCount ON
    |SELECT
    |    ID [Эл $Справочник.Контрагенты]
    |FROM
    |    спрКонтрагенты
    |WHERE
    |    ROW_ID In ("+стр+")
    |
    |
    |SELECT
    |    ID [Эл $Справочник.Контрагенты]
    |FROM
    |    спрКонтрагенты
    |--    left join #t1 on [#t1].к1 = ROW_ID
    |WHERE
    |--    ROW_ID Is not Null
    |    ROW_ID In (select к1 from #t1)
    |");
    
КонецПроцедуры


Текст запроса потом профайлером выцепил, и в студии уже анализировал.
1 Sorm
 
19.11.13
12:31
|WHERE
    |--    ROW_ID Is not Null
    |    ROW_ID In (select к1 from #t1))

Чего-чего??
2 ADirks
 
19.11.13
12:32
(1) проверял варианты, они абсолютно эквивалентны
3 1dvd
 
19.11.13
12:33
Это каменты чтоли?

|--
4 ADirks
 
19.11.13
12:34
(3) да, для SQL
5 ЧеловекДуши
 
19.11.13
12:34
(0) Запрос в топку :)
6 Sorm
 
19.11.13
12:35
(0) Я не очень понял, нафига left c условием, если можно inner, и где индекс на временной таблице?
8 Z1
 
19.11.13
12:36
так потому что про константы оптимизатор все знает
и учтет константы при созтавлении плана выполнения
а про содержимое временной таблицы оптимизатор может только предполагать.


Значительно улучшишь запрос с временной таблицей если создашь
на ней индекс ( кластерный индекс )
9 1dvd
 
19.11.13
12:36
*каменты
10 ADirks
 
19.11.13
12:37
(8) кластерный? щас проверю
11 ЧеловекДуши
 
19.11.13
12:38
(0) А где проверка, что временная таблица уже создана? :)

Пример:
//Создает временную таблицу на SQL сервере                
//Параметры:
//    ИмяТаблицы - имя временной таблицы, имена локальных таблиц должны
//                начинаться с символа #, глобальных с ##
//    ПоляТаблицы - имена и типы полей таблицы
//    
Функция глСоздатьВременнуюТаблицу(ИмяТаблицы,ПоляТаблицы) Экспорт
    //НЗ=глУстановитьНаборЗаписей();
    НЗ = СоздатьОбъект("ODBCRecordSet");
    попытка
        НЗ.УстБД1С();  
        
        Если глОтладкаSQL=1 Тогда
            НЗ.Отладка();
        КонецЕсли;
    исключение
        глСообщить("Ошибка при создании объекта ""ODBCRecordSet"", обратитесь к системному адмнистратору!", "!");
        Возврат 0;
    конецпопытки;
    
    ТекстЗапроса="
    |if exists (select * from tempdb..sysobjects
    |            where id = object_id('tempdb.."+ИмяТаблицы+"'))
    |drop table "+ИмяТаблицы+"
    |create table "+ИмяТаблицы+" ("+ПоляТаблицы+")
    |";
    Если НЗ.Выполнить(ТекстЗапроса) = 0 Тогда
        глСообщить(НЗ.GetLastError(), "!");
        НЗ.Закрыть();
        Возврат 0;
    КонецЕсли;    
    НЗ.Закрыть();
    
    Возврат 1;
КонецФункции
12 ЧеловекДуши
 
19.11.13
12:38
(7) Там все однополое :)
13 ADirks
 
19.11.13
12:42
(8) в исходном варианте получилось 84 / 16
но если select-лист сделать более приближенным к реальности

SELECT
    ID [Эл $Справочник.Контрагенты],
    ИНН

то получается 51 / 49
14 Sorm
 
19.11.13
12:44
(8) При таком объеме практически неважно:)

(0) А так низзья?

....

    |SELECT
    |    ID [Эл $Справочник.Контрагенты]
    |FROM
    |    спрКонтрагенты
    |   inner join #t1 on [#t1].к1 = ROW_ID
15 ADirks
 
19.11.13
12:50
(14) что inner, что left & is not null, что in  - абсолютно без разницы
16 Z1
 
19.11.13
12:51
(14) Да дело не в объемах, а том что куча это одно
а  хороший индекс это другое.
Хотя согласен стоит или нет что-то оптимизировать зависит от того что хочет узнать (0)

Кстати текст запроса (14) будет давать другой результат от (1)
если временная таблица допускает повторяющиеся элементы
17 КонецЦикла
 
19.11.13
13:39
Когда-то пихал в строку дофига значений, но не мерял
Смотря откуда брать, наверное
Время на формирование текста запроса тоже надо учитывать :)
Компьютеры — это как велосипед. Только для нашего сознания. Стив Джобс