Имя: Пароль:
1C
 
Как использовать свойство Индексы таблицы значений в 8.1?
0 TormozIT
 
гуру
09.03.07
21:21
ТаблицаЗначений.Индексы (ValueTable.Indexes)
ТаблицаЗначений (ValueTable)
Индексы (Indexes)
Использование:
Только чтение.
Описание:
Тип: ИндексыКоллекции. Содержит коллекцию индексов таблицы значений.
Возможен обмен с сервером.

Не могу понять, как использовать.
Помогите примером.
1 TormozIT
 
гуру
09.03.07
21:21
ИндексыКоллекции (CollectionIndexes)
ИндексыКоллекции (CollectionIndexes)
Элементы коллекции:
ИндексКоллекции
Для объекта доступен обход коллекции посредством оператора Для каждого … Из … Цикл. При обходе выбираются ИндексКоллекции.

Методы:
Добавить (Add)
Количество (Count)
Очистить (Clear)
Удалить (Delete)

Описание:
Список индексов коллекции.
См. также:
ИндексКоллекции
ТаблицаЗначений, свойство Индексы
2 TormozIT
 
гуру
09.03.07
22:27
Уже раз 20 упал конфигуратор в режиме отладки (потянуло обратно на 8.0).
8.1.6.38
Нигде не могу найти описания
3 Defender aka LINN
 
09.03.07
22:36
Гм... А ИндексКоллекции что такое? СП хотя бы процитируй :)
8.1, правда, сейчас нет, но может кто скажет.
4 jcage
 
09.03.07
22:37
v8: 8.1: Индексы таблицы значений. Назначение и методы использования

Насчет использовать - это просто.
   
   ТаблицаСОднимИндексом.Индексы.Добавить("Данные1");
   СделатьОтметкуВремени("   Время создания индекса на 1-у колонку (с): ");
   
   ТаблицаСДвумяИндексами.Индексы.Добавить("Данные1, Данные2");
   СделатьОтметкуВремени("   Время создания индекса на 2-е колонки (с): ");
   
   ТаблицаСТремяИндексами.Индексы.Добавить("Данные1, Данные2, Данные3");
   СделатьОтметкуВремени("   Время создания индекса на 3-и колонки (с): ");
   
Но вот что они дают - я так и не понял. Написал обработку для тестирования: время поиска по индексированным колонкам практически не отличается от поиска по обычным.
5 jcage
 
09.03.07
22:47
Собственно можете сами посмотреть:



Перем Генератор;
Перем СтрокаСимволов;
Перем ДлинаСтроки;
Перем Секунды;

Функция Таймер()
   Скрипт= новый ComОбъект("MSScriptControl.ScriptControl");
   Скрипт.Language="javascript";
   ТекущееВремя = Скрипт.eval("new Date().getTime()");
   Возврат ТекущееВремя;
КонецФункции

Функция ПолучитьСтроку()
   
   НоваяСтрока = "";
   Для СчВлож2 = 1 по 50 Цикл
       
       НоваяСтрока = НоваяСтрока + Сред(СтрокаСимволов, Генератор.СлучайноеЧисло(1, ДлинаСтроки), 1);
       
   КонецЦикла;    
   
КонецФункции

Процедура СделатьОтметкуВремени(ТекстСообщения = Неопределено)
   
   Если ТекстСообщения <> Неопределено Тогда
       Разность = Таймер() - Секунды;
       ЧислоСекунд = Цел(Разность/1000);
       Разность = Разность - ЧислоСекунд*1000;
   КонецЕсли;
   
   Секунды = Таймер();    
   
   Если ТекстСообщения <> Неопределено Тогда
       Сообщить(ТекстСообщения + ЧислоСекунд + "." + Разность);
   КонецЕсли;
   
КонецПроцедуры

Процедура КнопкаВыполнитьНажатие(Кнопка)
   
   ИсходнаяТаблицаЗначений = Новый ТаблицаЗначений;
   
   ОписаниеТиповСтрока = Новый ОписаниеТипов("Строка");
   ОписаниеТиповЧисло = Новый ОписаниеТипов("Число");
   
   ИсходнаяТаблицаЗначений.Колонки.Добавить("Данные1", ОписаниеТиповСтрока);
   ИсходнаяТаблицаЗначений.Колонки.Добавить("Данные2", ОписаниеТиповСтрока);
   ИсходнаяТаблицаЗначений.Колонки.Добавить("Данные3", ОписаниеТиповСтрока);
   
   ИсходнаяТаблицаЗначений.Колонки.Добавить("Сумма", ОписаниеТиповЧисло);
   
   Секунды = Таймер();    
   ДатаНачала = ТекущаяДата();
   Сообщить("Начало выполнения: " + ДатаНачала);
   
   Для Сч = 1 По КоличествоСтрок Цикл
       
       СтрокаТЧ = ИсходнаяТаблицаЗначений.Добавить();
       
       Для СчВлож = 1 По 3 Цикл
           
           СтрокаТЧ["Данные" + СчВлож] = ПолучитьСтроку();
           
       КонецЦикла;
       
       СтрокаТЧ.Сумма = КоличествоСтрок - Сч;

   КонецЦикла;
   
   СделатьОтметкуВремени("Время генерации таблицы значений (с): ");
       
   ТаблицаБезИндексов     = ИсходнаяТаблицаЗначений.Скопировать();
   ТаблицаСОднимИндексом  = ИсходнаяТаблицаЗначений.Скопировать();
   ТаблицаСДвумяИндексами = ИсходнаяТаблицаЗначений.Скопировать();
   ТаблицаСТремяИндексами = ИсходнаяТаблицаЗначений.Скопировать();
   
   СделатьОтметкуВремени("Время копирования таблиц значений (с): ");
   
   Сообщить("Создание индексов", СтатусСообщения.Информация);
   
   ТаблицаСОднимИндексом.Индексы.Добавить("Данные1");
   СделатьОтметкуВремени("   Время создания индекса на 1-у колонку (с): ");
   
   ТаблицаСДвумяИндексами.Индексы.Добавить("Данные1, Данные2");
   СделатьОтметкуВремени("   Время создания индекса на 2-е колонки (с): ");
   
   ТаблицаСТремяИндексами.Индексы.Добавить("Данные1, Данные2, Данные3");
   СделатьОтметкуВремени("   Время создания индекса на 3-и колонки (с): ");
   
   Сообщить("Копирование таблицы без индексов: ", СтатусСообщения.Информация);
   
   Тест1 = ТаблицаБезИндексов.Скопировать();
   Тест2 = ТаблицаБезИндексов.Скопировать();
   Тест3 = ТаблицаБезИндексов.Скопировать();
   
   СделатьОтметкуВремени("  Время копирования таблицы без индексов: ");
   Сообщить("  Свертка таблицы", СтатусСообщения.Информация);
   
   Тест1.Свернуть("Данные1", "Сумма");
   СделатьОтметкуВремени("      По 1-ой колонке: ");
   Тест2.Свернуть("Данные1, Данные2", "Сумма");
   СделатьОтметкуВремени("      По 2-ум колонкам: ");
   Тест3.Свернуть("Данные1, Данные2, Данные3", "Сумма");
   СделатьОтметкуВремени("      По 3-ем колонкам: ");
   
   
   Сообщить("Копирование таблицы с 1-м индексом: ", СтатусСообщения.Информация);
   
   Тест1 = ТаблицаСОднимИндексом.Скопировать();
   Тест2 = ТаблицаСОднимИндексом.Скопировать();
   Тест3 = ТаблицаСОднимИндексом.Скопировать();
   
   СделатьОтметкуВремени("  Время копирования таблицы с 1-м индексом: ");
   
   Сообщить("  Свертка таблицы", СтатусСообщения.Информация);
   
   Тест1.Свернуть("Данные1", "Сумма");
   СделатьОтметкуВремени("      По 1-ой колонке: ");
   Тест2.Свернуть("Данные1, Данные2", "Сумма");
   СделатьОтметкуВремени("      По 2-ум колонкам: ");
   Тест3.Свернуть("Данные1, Данные2, Данные3", "Сумма");
   СделатьОтметкуВремени("      По 3-ем колонкам: ");
   
   Сообщить("Копирование таблицы с 2-мя индексами: ", СтатусСообщения.Информация);
   
   Тест1 = ТаблицаСДвумяИндексами.Скопировать();
   Тест2 = ТаблицаСДвумяИндексами.Скопировать();
   Тест3 = ТаблицаСДвумяИндексами.Скопировать();
   
   СделатьОтметкуВремени("  Время копирования таблицы с 2-мя индексами: ");
   
   Сообщить("  Свертка таблицы", СтатусСообщения.Информация);
   
   Тест1.Свернуть("Данные1", "Сумма");
   СделатьОтметкуВремени("      По 1-ой колонке: ");
   Тест2.Свернуть("Данные1, Данные2", "Сумма");
   СделатьОтметкуВремени("      По 2-ум колонкам: ");
   Тест3.Свернуть("Данные1, Данные2, Данные3", "Сумма");
   СделатьОтметкуВремени("      По 3-ем колонкам: ");
   
   Сообщить("Копирование таблицы с 3-мя индексами: ", СтатусСообщения.Информация);
   
   Тест1 = ТаблицаСТремяИндексами.Скопировать();
   Тест2 = ТаблицаСТремяИндексами.Скопировать();
   Тест3 = ТаблицаСТремяИндексами.Скопировать();
   
   СделатьОтметкуВремени("  Время копирования таблицы с 3-мя индексами: ");
   
   Сообщить("  Свертка таблицы", СтатусСообщения.Информация);
   
   Тест1.Свернуть("Данные1", "Сумма");
   СделатьОтметкуВремени("      По 1-ой колонке: ");
   Тест2.Свернуть("Данные1, Данные2", "Сумма");
   СделатьОтметкуВремени("      По 2-ум колонкам: ");
   Тест3.Свернуть("Данные1, Данные2, Данные3", "Сумма");
   СделатьОтметкуВремени("      По 3-ем колонкам: ");

   
   СтруктураПоиска = Новый Структура("Данные1, Данные2, Данные3", ПолучитьСтроку(), ПолучитьСтроку(), ПолучитьСтроку());
   
   Сообщить("Поиск в таблице значений", СтатусСообщения.Информация);
   СделатьОтметкуВремени();
   
   НайденныеСтроки = ТаблицаБезИндексов.НайтиСтроки(СтруктураПоиска);
   СделатьОтметкуВремени("        Поиск в таблице без индексов (с): ");
   
   НайденныеСтроки = ТаблицаСОднимИндексом.НайтиСтроки(СтруктураПоиска);
   СделатьОтметкуВремени("        Поиск в таблице с одним индексом (с): ");
   
   НайденныеСтроки = ТаблицаСДвумяИндексами.НайтиСтроки(СтруктураПоиска);
   СделатьОтметкуВремени("        Поиск в таблице с двумя индексами (с): ");
   
   НайденныеСтроки = ТаблицаСТремяИндексами.НайтиСтроки(СтруктураПоиска);
   СделатьОтметкуВремени("        Поиск в таблице с тремя индексами (с): ");
   
КонецПроцедуры

Генератор = Новый ГенераторСлучайныхЧисел();
СтрокаСимволов = "0123456789ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮqwertyuiop[]asdfghjkl;'zxcvbnmm";
ДлинаСтроки = СтрДлина(СтрокаСимволов);
   


Достаточно сделать форму и на форме реквизит "КоличествоСтрок", который будет отвечать за количество строк ТЗ для тестирования. Весь код автоматически сгенерированный заменить на данный.
6 TormozIT
 
гуру
09.03.07
23:06
Спасибо jcage. Наконец я познаю их!
7 jcage
 
09.03.07
23:10
(6) Чем могу, рад помочь:)
8 TormozIT
 
гуру
09.03.07
23:10
Хотя получается то, что не познаю... Я тоже сравнивал замеры производительности.
Че то не вкурил я прироста. Дык еще с этими индексами отладка падает постоянно у меня. Наверное индексировать то не все типы можно, да только вот описания НЕТУ!
9 jcage
 
09.03.07
23:11
(8) Вот я и не вкурил прироста...
10 TormozIT
 
гуру
09.03.07
23:13
У меня важные процедуры, которые используют большое количество поисков по ТЗ. И я очень надеялся ускорить их за счет индексов. Но получил ШИШЬ =(
11 jcage
 
09.03.07
23:35
(10) На мой взгляд ускорить лучше за счет запросов к ТЗ.
12 jcage
 
09.03.07
23:36
(11) + пробовал свертку заменить на "Сгруппировать" - ускорение многократно.
13 TormozIT
 
гуру
09.03.07
23:42
(11) В моем случае не прокатит. Как я уже писал большое количество поисков. Это значит, что таблица будет каждый раз отправляться на сервер. Не думаю, что это ускорит процесс =)
14 TormozIT
 
гуру
10.03.07
10:10
Ап
15 jcage
 
10.03.07
13:19
(13) нафига? Один раз отправляешь на сервер, а потом ищешь в ней сколько надо раз.
16 TormozIT
 
гуру
10.03.07
13:27
(15) После каждого поиска возможна модификация.
17 jcage
 
10.03.07
13:44
Ну попробуй сравнить, что будет быстрее запросы или НайтиСтроки.

Уверен, что запросы.
18 TormozIT
 
гуру
10.03.07
14:10
Я уверен, что индексы именно для оптимизации именно таких задач нужны. Только практика пока не дает подтверждения. Нужна документация.

(17) У меня используется метод Найти() (поиск идет по одной колонке).
19 jcage
 
10.03.07
14:18
(18) а оптимизировать алгоритм за счет возможности хранить таблицы на сервере никак?
20 jcage
 
10.03.07
14:18
(19) + насчет индексов ты прав, только вот что это за зверь и как его есть - пока не понятно.
21 TormozIT
 
гуру
10.03.07
14:23
(19) Нет, это в общем случае временная таблица.
22 TormozIT
 
гуру
12.03.07
13:03
Для того, чтобы создать индекс, нужно добавить его в коллекцию индексов:

ТаблицаЗначений.Индексы.Добавить("Колонка1, Колонка2");

Применение индекса оправдано, если Вы выполняете множественный поиск по ТЗ. Например, когда у Вас есть цикл, в котором вызывается ТаблицаЗначений.НайтиСтроки или ТаблицаЗначений.Найти. При единичном поиске отличие между поиском по индексу и поиском без индекса не очень велико, даже на 1000000 элементов.

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

При поиске индекс используется только в том случае, если состав колонок индекса и состав колонок, по которым ведется поиск, совпадают.
23 TormozIT
 
гуру
12.03.07
13:09
Применил в алгоритме с интенсивным поиском по ТЗ.
В проверочном случае получил прирост 10% (2.08 сек против 2.28 сек). Там было порядка 500 поисков. Думаю, это неплохо.
24 TormozIT
 
гуру
13.03.07
10:32
Индексируются все типы
25 sindbad
 
22.07.07
10:23
Да вот решил поднять темку, просто самому было нужно использовать индексы для ускорения поиска. Так вот, замер производительности показал, что в таблице с 10'000 номенклатуры сама индексация (поле "ссылка") производится за 50 мс,

- среднее время поиска элемента с индексацией:  0,000065032 с
- среднее время поиска элемента без индексации: 0,013072343 с

Таким образом, с индексацией поиск осуществляется аж в 200 раз быстрее! Причем по моим наблюдениям памяти на индексацию выделяется примерно 100-150 Кб, по-моему данная фишка неплохо разгружает сервак, особенно в терминальном режиме.
Для тестирования был осуществлен поиск примерно 1000 элементов в обоих режимах, причем 90 процентов - это элементы, находящиеся в самом конце таблицы (с номером 9xxx), что позволило сделать тестирование достаточно объективным, по сравнению допустим с таблицей из 100-1000 элементов.
Даже без замера производительности можно было заметить разницу в скорости - с индексами нет даже намеков на какие-либо тормоза (в т.ч. и в конце таблицы), в обычном режиме тормоза усиливаются по мере продвижения курсора в конец таблицы, что вполне логично.

ps: Тестирование осуществлялось на движке 1С:Предприятие 8.1 (8.1.7.37), конфа "Управление торговлей", редакция 10.2 (10.2.13.1), режим работы - локальный (надо бы на сервере протестировать), комп - двухядерный P4 3 ГГц, память 1 ГБ DDR 2 на 800 шине, мать intel DG965RY, винт - 250 ГБ Seagate SATA-2 16M ncq 7200rpm, монитор 19' Samsung 940Fn :)

Жду ваши мнения по этому поводу.
Чтобы обнаруживать ошибки, программист должен иметь ум, которому доставляет удовольствие находить изъяны там, где, казалось, царят красота и совершенство. Фредерик Брукс-младший