0. ildarovich 6721 27.09.16 15:57 Сейчас в теме

Простой способ индексирования интервалов

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

Перейти к публикации

Комментарии
Избранное Подписка Сортировка: Древо
1. Makushimo 154 28.09.16 11:31 Сейчас в теме
абалдеть !
Как всегда прочитал с удовольствием и обязательно буду применять в работе.
2. Alias 153 28.09.16 12:21 Сейчас в теме
Очень красиво, спасибо большое. И вдобавок ещё и полезно. :)
3. igormiro 691 28.09.16 14:22 Сейчас в теме
Очередная статья мастера. По заголовку статьи знаешь, чья статься. Спасибо.
AlX0id; Kinestetik; wowik; Evil Beaver; webester; soulsteps; Liris; Noxie41; +8 Ответить
4. Sergey.Noskov 1079 28.09.16 14:23 Сейчас в теме
Очень интересно и наглядно.
Вопрос, Не пытались архитектуру регистра заточить под использование кластерного индекса? Судя по последнему плану запроса основную часть ресурсов потребляет операция "Поиск ключа", судя по всему это проверка части условия "..ДатаСменыСтатуса > &Т0.." + получение ресурса "Статус", сделав ДатаСменыСтатуса в составе измерений, уже можно получить профит, а если кластерным будет ключ [Проекция, Период, ДатаСменыСтатуса...], то должны получить максимальную скорость.
5. ildarovich 6721 28.09.16 15:16 Сейчас в теме
(4) Sergey.Noskov, такая мысль была.
Не стал этого делать, поскольку попробовал этот вариант на основной задаче: поиске интервалов. Первый план ему как раз и соответствует. Ощутимого прироста это не дало, поэтому на задаче о статусах пробовать уже не стал.
12. Sergey.Noskov 1079 29.09.16 16:58 Сейчас в теме
(5) а в диаграмме значения "Без индексирования" и "С индексированием" это сравнение каких запросов? Можно план запроса для "Без индексирования" увидеть?
13. ildarovich 6721 30.09.16 09:55 Сейчас в теме
(12) Sergey.Noskov, "с индексированием" это запрос с отбором по проекции:
ВЫБРАТЬ * ИЗ РегистрСведений.Дано 
ГДЕ Проекция В (&МассивПроекций) И &МоментВремени МЕЖДУ НачалоИнтервала И КонецИнтервала


Без индексирования - исходный запрос без такого отбора:
ВЫБРАТЬ * ИЗ Дано 
ГДЕ &МоментВремени МЕЖДУ НачалоИнтервала И КонецИнтервала

Вот его план (в двух видах в приложенных файлах):
Не увидел там ничего интересного, поэтому не стал приводить в статье.
Прикрепленные файлы:
ПланЗапросаБезИндексирования.txt
6. vspl 28.09.16 15:20 Сейчас в теме
Не хочу придираться к сути самой статьи, там все, наверное, правильно,
но для чистоты эксперимента в "Задаче о статусах заявок" нужно все-таки сравнивать быстродействие вот с этим запросом:

ВЫБРАТЬ * ИЗ РегистрСведений.СтатусыЗаявок.СрезПоследних(&Т0, Статус В (&Новый, &ВРаботе))

При условии, конечно, что Статус - индексированный

В этом случае результаты будут ИМХО не такие радужные
7. ildarovich 6721 28.09.16 15:25 Сейчас в теме
(6) vspl, это не эквивалентные запросы.
LordKim; ImHunter; Silenser; +3 Ответить
9. speshuric 1120 28.09.16 16:14 Сейчас в теме
(6) При небольшом количестве статусов (я думаю, до 50, могу проверить) СрезПоследних без явного отбора по заявкам всегда будет уходить в скан. Про это и была исходная задача. Задача описанная в этой статье - это вторая часть той задачи и она не эквивалентна срезу да и не решается только через срез.
ildarovich на самом деле молодец, сразу увидел главную граблю задачи по интервалам.
8. kare 21 28.09.16 15:26 Сейчас в теме
10. bulpi 157 28.09.16 21:21 Сейчас в теме
Задача со статусами , ИМХО, проще решается путем ввода условия
РегистрСведений.СтатусыЗаявок.СрезПоследних(&Т0, Период>=&ДатаПотериИнтереса)
, где ДатаПотериИнтереса =Т0- ИнтервалИнтересаВСекундах

, где ИнтервалИнтересаВСекундах - интервал, дальше которого пофиг на все незакрытые статусы. Такой интервал в реальных задачах всегда есть. Пусть даже большой. Например, год или два.
11. speshuric 1120 28.09.16 22:37 Сейчас в теме
(10) bulpi, Если этот интервал больше 10% от общего времени жизни - будут сканы. Точнее так: в 8.2 будет сканирование большого диапазона кластеризованного индекса, в 8.3 скорее всего будет полный скан (судя по освещённым в Sergey.Noskov изменениям).
14. user614720_vinzax 30.09.16 10:00 Сейчас в теме
Правда есть один забавный момент - есть такая константа "НеИспользоватьРазделениеПоОбластямДанных", так вот чтобы был доступен пункт с дополнительными отчетами и обработками она должна быть установлена в "Истина". Устанавливаться она должна, по идее, автоматически, но, видимо, разработчики БСП где-то что-то упустили и по умолчанию установлено значение "Ложь".
Можно зайти через "все функции", найти эту константу и установив значение "Истина" получить доступ к настройке внешних отчетов и обработок.
15. Serg O. 172 15.06.17 11:12 Сейчас в теме
крутатень! Ещё одно доказательство, что Правильная архитектура - очень важна!

мат. подход нужен, когда уже не помогает подход с матом
user656955_chel1C; +1 Ответить
17. kasper076 48 07.07.17 07:58 Сейчас в теме
Решил "реиндексировать" РС "СостоянияСогласованияЗаявок" УПП. При заполнении реквизита "Проекция" периодически возникала ошибка "Неправильное значение аргумента встроенной функции (Log)". Анализ показал, что в случае когда соседние записи в РС идут с одной и той же датой в поле период, то код
log(Макс(До - От, От - До)
выдает ошибку, т.к. log(0) не существует. Как решить эту проблему? Я понимаю, что записи в пределах секунды разнесены, но как учесть это в алгоритме расчета проекции не понимаю.
18. Release 07.07.17 08:01 Сейчас в теме
(17)Почему бы для До, От не использовать МоментВремени()?
19. kasper076 48 07.07.17 08:24 Сейчас в теме
(18) между моментами времени нельзя вычислить разность.
20. ildarovich 6721 07.07.17 09:47 Сейчас в теме
(17) Проще всего заменить выражение
Масштаб = pow(2, 99 - Цел(99 - Окр(log(Макс(До - От, От - До)) / log(2), 10)));
выражением
Масштаб = 1;
Тогда в следующем цикле будет выполняться больше итераций, а результат будет тем же. Ну, а если все же хочется убрать "лишние" итерации, то нужно проверить условие "От = До". Если оно выполняется, то масштаб принять равным единице:
Масштаб = ?(От = До, 1, pow(2, 99 - Цел(99 - Окр(log(Макс(До - От, От - До)) / log(2), 10))));
Кажется, так.
21. kasper076 48 07.07.17 10:06 Сейчас в теме
(20) Спасибо. Сейчас попробую.
Еще такой момент. Возможно обработка "Реиндексация" писалась на скорую руку и предполагалось, что конечный пользователь сам ее оптимизирует. Спасибо и за это. А возможно что-то упускаю и нужно было сделать именно так, как сделано.
Вот что есть сейчас:
	НаборЗаписей = РегистрыСведений.СтатусыЗаявок.СоздатьНаборЗаписей();
	НаборЗаписей.Прочитать();
	Таблица = НаборЗаписей.Выгрузить();
	Таблица.Сортировать("Заявка, Период");

При наличии в ТЗ ~2,5 млн строк Таблица.Сортировать("Заявка, Период") выполняется оч долго. Сделал так:
	Запрос = Новый Запрос(
	"ВЫБРАТЬ *
	|ИЗ
	|	РегистрСведений.СостоянияСогласованияЗаявок КАК СостоянияСогласованияЗаявок
	|
	|УПОРЯДОЧИТЬ ПО
	|	Заявка,
	|	Период
	|АВТОУПОРЯДОЧИВАНИЕ");
	
	Таблица = Запрос.Выполнить().Выгрузить();
Показать
22. ildarovich 6721 07.07.17 11:13 Сейчас в теме
(21) Если вы про обработку "Реиндексация" из примеров к статье, то все так и было.
Если реиндексацию необходимо делать не один раз, а часто, то интервалы лучше находить на основе алгоритма из статьи: Быстрое определение интервалов в запросе. Если постараться, то и проекцию можно сразу в запросе посчитать.
Оставьте свое сообщение
Новые вопросы с вознаграждением
Автор темы объявил вознаграждение за найденный ответ, его получит тот, кто первый поможет автору.

Вакансии

Бизнес-архитектор 1С, ведущий консультант
Санкт-Петербург
Полный день

Руководитель проектов 1С
Санкт-Петербург
Полный день

Программист 1С
Краснодар
зарплата от 80 000 руб. до 160 000 руб.
Полный день

Консультант 1 С
Краснодар
зарплата от 50 000 руб. до 150 000 руб.
Полный день

Консультант-методолог 1С
Краснодар
зарплата от 110 000 руб.
Полный день