gifts2017

Размышления и изыскания по использованию индексов ТЗ

Опубликовал kadr (kadr) в раздел Программирование - Практика программирования

Размышления и изыскания по использованию индексов ТЗ

Не статья, так - заметка. 
В ходе решения задачи по сохранению ссылок объектов БД в виде числа DWORD возникла мысль использовать регистр для хранения кода DWORD и ссылки на объект. 
Было решено протестировать скорость выборки на примере таблицы значений.
Для выборки использовалась новая фича 1С - индексы таблицы значений.

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

Диагностические сообщения при использовании индекса ТЗ (поиск 5000 и 50 значений):

    Время создания таблицы из 1 000 000 без создания индекса составило: 13 016 мсек
    Создание индекса для 1 000 000 записей составило 7 265 мсек
    Поиск в индексированной ТЗ 5 000 записей занял 63 мсек. Найдено 47 совпадений из 5 000 значений

    Время создания таблицы из 1 000 000 без создания индекса составило: 12 797 мсек
    Создание индекса для 1 000 000 записей составило 7 250 мсек
    Поиск в индексированной ТЗ 50 записей занял 0 мсек. Найдено 0 совпадений из 50 значений



И без индекса (поиск 5000 и 50 значений):

    Время создания таблицы из 1 000 000 без создания индекса составило: 13 063 мсек
    Поиск в НЕ индексированной ТЗ 5 000 записей занял 595 859 мсек. Найдено 47 совпадений из 5 000 значений

    Время создания таблицы из 1 000 000 без создания индекса составило: 12 907 мсек
    Поиск в НЕ индексированной ТЗ 50 записей занял 5 984 мсек. Найдено 0 совпадений из 50 значений


Вывод одназначен - при использовании выборок из временных таблиц значений стоит использовать индексы.
Код для Интегратора для проверки

 

Скрипт = Новый COMОбъект("MSScriptControl.ScriptControl");
  Скрипт.language = "javascript";
  
  ЧислоЗаписей = 1000000;
  ЧислоИтерацийПоиска = 50;
  
  ОчиститьСообщения();
  Сообщить("Идет создание м наполнение таблицы значений");
  
  ВремяСтарта = Число(Формат(Скрипт.Eval("new Date().getTime()"),"ЧГ=0"));
  
  ТестТабл = Новый ТаблицаЗначений;
  ТестТабл.Колонки.Добавить("Код");
  ТестТабл.Колонки.Добавить("Значение");
  
  Для Сч = 1 По ЧислоЗаписей Цикл
     СтрокаТЗ = ТестТабл.Добавить();
     СтрокаТЗ.Код = Сч;
     СтрокаТЗ.Значение = Строка(Новый УникальныйИдентификатор());
  КонецЦикла;      
  
  Сообщить("Время создания таблицы из "+Строка(ЧислоЗаписей)+" без создания индекса составило: "+
          Строка(Число(Формат(Скрипт.Eval("new Date().getTime()"),"ЧГ=0"))-ВремяСтарта)+" мсек");
        
  // создание индекса        
  ВремяСтарта = Число(Формат(Скрипт.Eval("new Date().getTime()"),"ЧГ=0"));
  ТестТабл.Индексы.Добавить("Код");
  Сообщить("Создание индекса для "+Строка(ЧислоЗаписей)+" записей составило "+
       Строка(Число(Формат(Скрипт.Eval("new Date().getTime()"),"ЧГ=0"))-ВремяСтарта)+" мсек");
     
 // поиск в таблице
 ГСЧ = Новый ГенераторСлучайныхЧисел(ЧислоЗаписей);
 
 ВремяСтарта = Число(Формат(Скрипт.Eval("new Date().getTime()"),"ЧГ=0"));
 
 ЧислоСовпадений = 0;
 Для Сч = 1 по ЧислоИтерацийПоиска Цикл
     КодПоиска = ГСЧ.СлучайноеЧисло(0,ЧислоЗаписей*100);
     СтрокаТЧ = ТестТабл.Найти(КодПоиска,"Код"); 
     Если СтрокаТЧ <> Неопределено тогда
         ЧислоСовпадений = ЧислоСовпадений+1;
     КонецЕсли;     
 КонецЦикла; 
 
 Сообщить("Поиск в НЕ индексированной ТЗ "+Строка(ЧислоИтерацийПоиска)+" записей занял "+
       Строка(Число(Формат(Скрипт.Eval("new Date().getTime()"),"ЧГ=0"))-ВремяСтарта)+" мсек. "+
     "Найдено "+ Строка(ЧислоСовпадений) + " совпадений из " + Строка(ЧислоИтерацийПоиска)+" значений");     



Предложения по поводу хранения ссылок на объект в DWORD приветствуются.
2009-04-21 kadr

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Сергей Дудаков (Anything) 22.04.09 09:57
Согласен. Использование индексов для ТЗ ускоряет поиск на порядок.

Тут важно отметить, что при поиске через отбор методом НайтиСтроки() важен порядок указания полей. Порядок в отборе должен совпадать с порядком в индексе.

Например, если мы ищем строки так:
Код
Отбор = Новый Структура;
Отбор.Добавить("Значение", ЗначениеПоиска);
Отбор.Добавить("Код", КодПоиска);

НайденныеСтроки = ТестТабл.НайтиСтроки(Отбор);
Показать полностью


То и индекс надо создавать соответствующим образом:
Код
ТестТабл.Индексы.Добавить("Значение, Код");
Показать полностью


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

Например:
Код
ТестТабл.Индексы.Добавить("Код, Значение");
ТестТабл.Индексы.Добавить("Значение, Код");
ТестТабл.Индексы.Добавить("Код, Наименование");
и т. п.
Показать полностью
2. Андрей Янакаев (YAN) 22.04.09 10:17
Очень полезно использовать индексы, правда надо не забывать после дописать следующий код:

ТестТабл.Индексы.Очистить();
3. Сергей Старых (tormozit) 18.05.09 23:10
(1) Вы неправы. Структура не является упорядоченной коллекцией. Скорее при поиске платформа сама переставляет поля, подбирая оптимальный порядок.
4. Сергей Дудаков (Anything) 19.05.09 11:59
(3) Скорее, платформа не заморачивается с оптимальным порядком, а просто берет поля в порядке их описания.

А насчет упорядоченности структуры - есть такой оператор: "Для Каждого ... Из ...".

Проверьте результат двух вариантов:

1.
Код
Структура = Новый Структура("Поле1, Поле2");
Для Каждого Элемент Из Структура Цикл
   Сообщить(Элемент.Ключ);
КонецЦикла;
Показать полностью


2.
Код
Структура = Новый Структура("Поле2, Поле1");
Для Каждого Элемент Из Структура Цикл
   Сообщить(Элемент.Ключ);
КонецЦикла;
Показать полностью
5. Сергей Старых (tormozit) 19.05.09 12:11
(4) Лучше изучайте документацию. Если ваш опыт говорит, что из А следует Б, это еще не значит что из А всегда следует Б. В неупорядоченных коллекциях не гарантирован порядок обхода элементов.
6. Сергей Дудаков (Anything) 19.05.09 13:54
(5) Я и делился опытом. Мой опыт показывает, что платформа реагирует именно так. Не зависимо от того, что написано в документации.
7. Артур Аюханов (artbear) 19.05.09 19:03
(5) А я почти согласен с (4), что "(3) Скорее, платформа не заморачивается с оптимальным порядком, а просто берет поля в порядке их описания."

По многолетнему опыту работы с 1С (77 и 8) и разработке ВК 1С++/ФормЕкс на базе внутренностей 1С знаю, что общие объекты типа СЗ, ТЗ, Структуры и т.д. 1С практически не оптимизирует :(

ЗЫ хотя, конечно, только точное тестирование может показать истину.
Пример с циклом "для каждого" может быть и не характерен :)
8. Сергей Старых (tormozit) 19.05.09 19:13
Зачем строить предположения, если разработчики платформы давали уже не раз четкие разъяснения по этому вопросу? При выполнении поиска в ТЗ по отбору в виде структуры выполняется подбор индекса по простому алгоритму: перебираем элементы структуры и вычеркиваем индексы, которые не подходят; из оставшихся вычеркиваем, имеющие лишние элементы.
9. Артур Аюханов (artbear) 28.01.10 17:55
Ну т.е. в (8) цитатой "перебираем элементы структуры" подтверждено (4) и (7)
т.к. перебор идет просто в порядке описания.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа