Поговорим о некоторых особенностях таблицы значений 1С.  Как сделать работу с ней быстрее в 100 раз.

таблица значений 1С, оптимизация таблицы значений 1С

таблица значений 1С

Таблица значений 1С используется для оперативного хранения данных  и их обработки. При большом числе строк скорость поиска данных резко снижается. Многие программисты недооценивают важность применения индексов, при поиске информации в таблице значений. Я намерен показать вам, что применение индексов ускоряет работу с ТЗ (таблица значений 1С) до 100 раз.

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

  • Извлекается 20 тысяч строк из  табличной части документа "Реализация" в таблицу значений. Называется она Т1.
  • Сделал копию этой же таблицы значений, вторую таблицу, назвал ее Т2. Итак, получилось 2 таблицы значений, Т1 и Т2, в каждой по 20 тысяч строк.
  • Далее в цикле от 1 до 5 мы делаем пять проходов. Проход заключается в следующем:
  • В цикле (который вложен в цикл от 1 до 5) перебираются все строки таблицы значений Т1, все 20 тысяч строк.
  • Для каждой текущей строки Т1 извлекаем из таблицы значений Т1 значение в колонке "Сумма" - это число.
  • Ищем строку в таблице значений Т2, содержащую в колонке "Сумма"  тоже самое число, которое которое извлекли на предыдущем шаге.
  • Измеряем время каждого прохода в миллисекундах и выводим на экран.

Другими словами, перебирая все строки одной таблицы значений 1С и запоминая значение столбца "Сумма" , мы ищем в другой таблице значений строку с той же самой суммой. Используется метод  таблицы значений "Найти".  В одном проходе операция поиска выполняется 20 тысяч раз. Проходов всего пять. Они необходимы для усреднения результатов эксперимента.

Ниже вы видите таблицу результатов работы теста. Второй столбец отражает время выполнения каждого из пяти проходов в обычном, не оптимизированном варианте запуска, а под столбцом стоит суммарное время выполнения теста, равное 279641 миллисекунды, или примерно 279 секунд. В третьем столбце показано время выполнения того же теста, но с оптимизированным вариантом поиска, с использованием индекса в таблице значений. Для наглядности я добавил в табличку время, затрачиваемое на создание индекса (первая строчка под заголовком), оно очень мало, всего 0, 047 секунды. Суммарное время выполнения теста во втором варианте равно 2781 миллисекунды, или 2,78 секунды.

Итак, в первом варианте имеем  - 279 секунд, во втором варианте - 2,78 секунд. Разница в 100 раз ! Причем, такое ускорение достигается добавлением всего ОДНОЙ СТРОЧКИ КОДА!

Время выполнения, миллисекунды
№ тестового запуска 1 вариант, обычный 2 вариант, оптимальный
время на создание индекса - 47
1 46531 563
2 55516 547
3 60969 531
4 58688 562
5 57937 531
Итоговое время 279641 2781
Ускорение в раз: 100,5541172

Вот полный код примера:

Процедура кнИндексТаблицыЗначенийНажатие(Элемент)
  // создаем запрос для выборки данных
  Запрос = Новый Запрос;
  Запрос.Текст =
  "ВЫБРАТЬ ПЕРВЫЕ 20000
  | РеализацияТовары.Ссылка,
  | РеализацияТовары.НомерСтроки,
  | РеализацияТовары.Количество,
  | РеализацияТовары.Сумма,
  | РеализацияТовары.Товар
  |ИЗ
  | Документ.Реализация.Товары КАК РеализацияТовары";
  // помещаем выбранные данные в таблицу значений Т1
  Т1 = Запрос.Выполнить().Выгрузить();
  // создаем таблицу значений Т2 путем копирования содержимого таблицы значений Т1
  Т2 = Т1.Скопировать();
  НачДобавленияИндекса = ПолучитьВремяВМиллисекундах();
  Т2.Индексы.Добавить("Сумма"); // ВОТ ЭТО САМАЯ ВАЖНАЯ СТРОЧКА, ДОБАВЛЕНИЕ ИНДЕКСА ПО КОЛОНКЕ "СУММА"
  КонДобавленияИндекса = ПолучитьВремяВМиллисекундах();
  Сообщить("Время добавления индекса " + (КонДобавленияИндекса - НачДобавленияИндекса) + " мс" );
  Сообщить("Всего строк в нашей таблице значений: " + Т2.Количество());
  // организуем цикл из пяти проходов, по-сути - пять раз прогоняем тест
  Для Сч = 1 По 5 Цикл
    Начало = ПолучитьВремяВМиллисекундах(); // запоминаем время начала
    НайденоРаз = 0;
    Для Каждого Стр Из Т1 Цикл                        // перебираем все строки таблицы Т1
      ОбработкаПрерыванияПользователя();
      // ищем в таблице Т2 строку, в которой колонка "Сумма"
      // совпадает с текущим значением "Сумма" таблицы Т1
      НайденнаяСтрока = Т2.Найти(Стр.Сумма, "Сумма");
      // Если совпадение зафиксировано (строка найдена), увеличиваем счетчик найденных строк
      Если НайденнаяСтрока <> Неопределено Тогда
        НайденоРаз = НайденоРаз + 1;
      КонецЕсли;
    КонецЦикла;
    // получаем время завершения цикла перебора строк таблицы Т1
    Конец = ПолучитьВремяВМиллисекундах();
    // сообщаем номер прохода теста, количество найденных совпадений и время выполнения в миллисекундах
    Сообщить("Проход № " + Сч);
    Сообщить("Найдено раз:" + НайденоРаз);
    Сообщить("Время выполнения " + Строка(Конец-Начало) + " миллисекунд");
  КонецЦикла; // уходим делать следующий проход
КонецПроцедуры

Пример откомментирован, и должен быть понятен. Главное заключается в строчке Т2.Индексы.Добавить("Сумма"); Мы сообщаем 1С, что мы собираемся выполнять операцию поиска по колонке "Сумма", в таблице значений Т1 и требуем создать индекс по этой колонке. Система создает индекс, и далее при всех операциях поиска по колонке "Сумма" использует его автоматически. Следует отметить, что созданный индекс действует только для поиска по колонке "Сумма", так как создан для этой колонки. Если нам нужны другие колонки для поиска, следует создать соответствующие индексы, с указанием нужных имен колонок.

К одной таблице мы можем создать несколько индексов, если мы собираемся искать значения для разных столбцов. Индексы хранятся в коллекции индексов таблицы значений 1С, что следует из кода: ТЗ.Индексы.Добавить(ИмяКолонки)

Если нам нужен поиск по комбинации значений колонок, например, одновременно по колонкам "Количество" и "Сумма" - следует создать составной индекс: Т2.Индексы.Добавить("Количество, Сумма") Такой индекс будет задействован, когда мы ищем значение в таблице при помощи метода "НайтиСтроки()" Например:

МассивНайденныхСтрок = Т2.НайтиСтроки(Новый Структура("Количество, Сумма", ИскомоеКоличество, ИскомаяСумма));

Функции 1С, используемые в тексте примера.
С уважением, Дегтярев Роман.

Как научиться программировать в 1С с нуля?

Как работать программистом 1С и получать до 150 000 рублей в месяц?

ЗАПИШИСЬ НА БЕСПЛАТНЫЙ

2-НЕДЕЛЬНЫЙ КУРС

"ПРОГРАММИРОВАНИЕ в 1С ДЛЯ НОВИЧКОВ"

Курс придет на электронную почту. Стань программистом, выполняя пошаговые задания.

Для участия нужен только компьютер и интернет

Бесплатный доступ на курс:



Комментарии для тех, кто VKontakte


4 комментария: Таблица значений 1С. Оптимизация скорости в 100 раз

Оставить комментарий

Ваш email не будет опубликован. Обязательные поля отмечены *

Вы можете использовать это HTMLтеги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Интернет-курс "Программирование в 1С с нуля"

Учись программировать и зарабатывать до
150 000 руб. в месяц! ТОЛЬКО СЕГОДНЯ - БЕСПЛАТНЫЙ ДОСТУП К КУРСУ!

Присоединяйся, тут все свои!