Имя: Пароль:
1C
1С v8
Ускорить запрос. Пятничный мозговой штурм!
0 Double_Medved
 
20.12.19
10:21
Добрый день.

Вопрос не влез в заголовок.

Сферический конь в вакууме:

Есть справочник магазинов. Есть инфа по акциям (сама акция - это документ, в нем период действия , всякие условия, (2 даты - типа с начала декабря по конец декабря), и длинная табличная часть со списком магазинов, тысячи их может быть)

Вопрос - как мне ускорить запрос "Какие акции есть 10 декабря в таком-то магазине"?

Думаю сделать регистр сведений, с измерением магазин, акция, и ДатаНачала и ДатаКонца.

Но меня смущает что 2 даты - регистр делать получается не периодический?
Имеет ли смысл делать индексацию полей?
Быстрее будет сделать отбор по магазину, положить во временную таблицу, и дальше делать отбор по датам?
Или сразу наложить отбор "ДатаЗапроса>=ДатаНачала" и "ДатаЗапроса<=ДатаКонца"?
Или лучше вообще при проведении документа типа "акция на декабрь" писать в регистр 31 запись на каждый магазин, на каждый день? Но так что-то совсем дохрена записей будет

Пятница, мозговой шторм начинается. Принимаю самые смелые идеи, и буду отписываться какая хрень получается
1 RomanYS
 
20.12.19
10:25
(0) периодический регистр
или 2 записи: начало и конец с ресурсом состояния,
или начало в период конец в ресурс.
Проверка в любом случае срезом
2 Волшебник
 
20.12.19
10:26
Изучи как устроен регистр с кадровыми данными физлиц в ЗУПе.
3 Cyberhawk
 
20.12.19
10:29
Так к ТЧ справочника и сделай запрос
4 Dmitrii
 
гуру
20.12.19
10:29
Если это задача оперативного учета и необходимо знать текущие действующие прямо сейчас акции, то я бы отказался вообще от дат с указанием периода действия, а хранил бы только актуальные акции, которые действуют.
В другом регистре хранил бы все данные (вместе с периодом действия) и регламентным заданием каждую ночь в 00:01:00 обновлял бы данные из регистра с периодами данные в оперативном регистре.
Естественно оперативный регистр не периодический.

Но этот изврат имеет смысл, только если производительность действительно критична. В противном случае, например см.(2).
5 d4rkmesa
 
20.12.19
10:31
(0) Ну допустим: Регистр сведений, периодический(в пределах дня), подчинен регистратору. Измерения: Организация, Получатель (Контрагент или Партнер, или что там у вас в конфе), Номенклатура/Набор номенклатуры, измерение или несколько измерений с условиями акции, Ресурсы: ЗначениеСкидки(если скидка) или Бонус(если скидка натуральная, т.е. другим товаром), Реквизиты: ДатаОкончания(для ограничения результата СрезПоследних).
6 Cyberhawk
 
20.12.19
10:32
Самый смак будет, когда захочется узнать какие акции действуют не на конкретный момент времени, а в заданном интервале
7 Cyberhawk
 
20.12.19
10:33
+(6) Так что проиндексировать придется оба поля с датами
8 Cyberhawk
 
20.12.19
10:34
А уж куда ты их там засунешь - в ТЧ, в реквизиты / ресурсы / измерения периодического / непериодического независимого / зависимого регистра - с этой точки зрения особо не влияет
9 Double_Medved
 
20.12.19
10:43
Нужно скорее всего будет и на дату, и на период дат и т.д.
10 Double_Medved
 
20.12.19
10:44
(8)То есть скорость будет в основном зависеть от того, индексируемые поля или нет?
11 Cyberhawk
 
20.12.19
10:45
(10) Взял бы уже и давно план своего требующего ускорения запроса посмотрел. Сколько строк затронуто, скан там или сик, кластерного или некластерного.
12 Double_Medved
 
20.12.19
10:49
(11)База серверная, постгрес. Сколько строк будет пока не знаю, хочется изначально технически правильно сделать.

Насколько я понимаю - лезть в табличную часть документов это совсем не оптимальный запрос, поэтому и спросил - будет ли лучше сделать регистр сведений?
13 Double_Medved
 
20.12.19
11:05
Создаю тестово 1000 документов по 2000 строк. Не то что фузиновцы
14 arsik
 
гуру
20.12.19
11:07
(12) По скорости будет разницы не будет. Что ты по ТЧ запрос сделаешь, что по регистру
15 H A D G E H O G s
 
20.12.19
11:39
(0) РС прям как ты описал, порядок измерений другой

Магазин, ДатаНачала и ДатаКонца, акция.

Ничего индексировать не надо.
16 Cyberhawk
 
20.12.19
11:39
(12) "лезть в табличную часть документов это совсем не оптимальный запрос, поэтому и спросил - будет ли лучше сделать регистр сведений?" // С точки зрения производительности чтение ТЧ и чтение регистра - это чтение одной плоской таблицы.
(14) Отличия только в неотключаемых (из коробки) индексах, если читающий запрос в обоих случаях попадает в индекс более-менее одинакового размера и структуры, то отличый быть не должно.
17 Cyberhawk
 
20.12.19
11:40
(15) Не думаю, что он догадается (по крайней мере планировал) делать дату конца измерением
18 Double_Medved
 
20.12.19
11:56
(18)так мне же на Мисте уже так насоветовали. Ща вот проверяю, будет ли толк
19 unenu
 
20.12.19
11:57
(0) в ЗУПЕ такие задачи успешно решают технологией "интервальные регистры сведений" и всякие периодические оттуда почти выпилены.

эти механизмы работают быстрее, главное понять как они работают и избавиться от ломки периодических данных.
20 dk
 
20.12.19
11:59
интересно появятся в 1с произвольные составные индексы? тогда и без регистра сведения можно было бы обойти
21 Fragster
 
гуру
20.12.19
11:59
регистр остатков :)
22 Fragster
 
гуру
20.12.19
12:00
документ старта акций делает + на начало акции и - на конец
23 Double_Medved
 
20.12.19
12:04
Но все равно же пихать в измерение ссылку на сам документ (на акцию).
24 Fragster
 
гуру
20.12.19
12:08
(23) ну да
25 Double_Medved
 
20.12.19
12:19
Замеры:
1000 документов по 2000 строк

Запрос "какие акции действуют на выбранном 1 магазине на конкретную дату"

В каждом варианте сделал по 10 замеров времени, выбрал среднее

1)Запрос напрямую к магазину в табличной части + отбор по "ДатаЗапроса>=Акция.ДатаНачала" и "ДатаЗапроса<=Акция.ДатаКонца"

В среднем 0.15 секунд

2)Запрос к срезу последних регистра сведений, где ресурс "Статус акции" = Активна/Кончилась

В среднем 0.017 секунд

Но увеличение объема данных соответственно, за счет записей в регистр + время на проведение документа
26 arsik
 
гуру
20.12.19
12:35
(25) Покажи запрос 1) Явно где то косяк.
27 Fragster
 
гуру
20.12.19
12:38
(25) на самом деле можно отказаться от тч, а сделать вместо неё программную таблицу и заполнять её из регистра при чтении а при записи - распихивать прямо в набор обратно. проведение и непроведение пусть рулит только галочкой активности.
28 Fragster
 
гуру
20.12.19
12:39
а сами записи в РС пусть будут всегда
29 H A D G E H O G s
 
20.12.19
12:43
(27) Галочка "Активность", не входящая в кластерный индекс, тебе потом спасибо скажет.
30 Fragster
 
гуру
20.12.19
12:51
(29) ну зачем-то же её придумали... и в типовых в операции бух она используется.
31 Fragster
 
гуру
20.12.19
12:51
в крайнем случае можно пихать у непроведенного документа в тч а при проведении удалять из тч и пихать в рс. при отмене проведения - делать обратное преобразование.
32 Fragster
 
гуру
20.12.19
12:52
если размер прям критичен
33 Жан Пердежон
 
20.12.19
13:13
(25) пиши каждую дату из периода (РС (Магазин, ДатаДействия, Акция)) - будет самое быстрое
34 pechkin
 
20.12.19
13:21
тысячи строк - это нично.
вот если бы миллионы были
35 singlych
 
20.12.19
13:26
В ЗУПе уже все придумали. Когда уже они пихнут это в БСП...
36 Double_Medved
 
20.12.19
13:37
(26)Первый вариант:

Запрос.Текст =
        "ВЫБРАТЬ
        |    АкцииПокупатели.Ссылка
        |ИЗ
        |    Документ.Акции.Покупатели КАК АкцииПокупатели
        |ГДЕ
        |    АкцииПокупатели.ТорговаяТочка = &ТорговаяТочка
        |    И АкцииПокупатели.Ссылка.ДатаН <= &ДатаЗапроса
        |    И АкцииПокупатели.Ссылка.ДатаК >= &ДатаЗапроса";
37 Double_Medved
 
20.12.19
13:38
(26)Второй вариант

Запрос.Текст =
        "ВЫБРАТЬ
        |    АкцияСрезПоследних.Акция КАК Ссылка,
        |    АкцияСрезПоследних.ТорговаяТочка
        |ИЗ
        |    РегистрСведений.Акция.СрезПоследних(&ДатаЗапроса, ТорговаяТочка = &ТорговаяТочка) КАК АкцияСрезПоследних
        |ГДЕ
        |    АкцияСрезПоследних.Статус = &Активна";
38 Double_Medved
 
20.12.19
13:40
(33)Переживаю что при установке акции на год на 2000 магазинов получу 2000*365 = 730000 записей
39 Double_Medved
 
20.12.19
13:41
А так в принципе сделал примерно как ЦеныНоменклатуры регистр
40 novichok79
 
20.12.19
13:45
при первом приближении:
зачем эта периодичность вообще?
я бы сделал непериодический регистр сведений
измерения:
магазин, дата начала и дата окончания.
ресурс: естьакция - булево
или вообще без ресурсов,
показатель наличия акции на магазин - присутствие магазина в заданном интервале
соответственно, индекс на даты и магазины в измерениях.

запрос внутренним джойном по магазинам и по наличию в заданном интервале
41 palsergeich
 
20.12.19
13:47
(38) Всего то, даже миллиона нет, нашел о чем переживать
42 RomanYS
 
20.12.19
13:53
(37) А если дату окончания засунуть в ресурс и заменить условие на статус заменить на АкцияСрезПоследних.ДатаОкончания >= &ДатаЗапроса?
Записей станет в два раза меньше, интересно, асколько условие будет медленнее/быстрее
43 arsik
 
гуру
20.12.19
13:56
(36) Так неправильно делать. нужно примерно так.
ВЫБРАТЬ
    ЗаказПокупателя.Ссылка КАК Ссылка
ИЗ
    Документ.ЗаказПокупателя.Товары КАК ЗаказПокупателяТовары
        ЛЕВОЕ СОЕДИНЕНИЕ Документ.ЗаказПокупателя КАК ЗаказПокупателя
        ПО ЗаказПокупателяТовары.Ссылка = ЗаказПокупателя.Ссылка
ГДЕ
    ЗаказПокупателя.Дата МЕЖДУ &Дата1 И &Дата2
    И ЗаказПокупателяТовары.Номенклатура = &Номенклатура
44 arsik
 
гуру
20.12.19
13:56
+ (43) Только не "ЛЕВОЕ СОЕДИНЕНИЕ", а "ВНУТРЕННЕЕ СОЕДИНЕНИЕ"
45 arsik
 
гуру
20.12.19
14:01
+(44)
ВЫБРАТЬ
    Акции.Ссылка КАК Ссылка
ИЗ
    Документ.Акции.АкцииПокупатели КАК АкцииАкцииПокупатели
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.Акции КАК Акции
        ПО АкцииАкцииПокупатели.Ссылка = Акции.Ссылка
ГДЕ
    &ДатаЗапроса МЕЖДУ Акции.ДатаН И Акции.ДатаК
    И АкцииАкцииПокупатели.ТорговаяТочка = &ТорговаяТочка
46 Double_Medved
 
20.12.19
14:40
(45)Примерно тоже самое получилось (по скорости). О,15 секунд
47 RomanYS
 
20.12.19
14:42
(45) так может условия тогда в связи перенести? Иначе непонятно для чего явное соединение и чем оно лучше неявного в(36)
48 dk
 
20.12.19
14:51
1. а фильтр по товару не интересен?
2. 0,15 сек на получение 1000 записей не такой плохой результат
3. почему период - на практике должна интересовать конкретная дата а не период
49 Double_Medved
 
20.12.19
14:51
(47)Так мне по датам отбор делать надо, а даты это реквизит документа. То есть если в табличной части делать отбор через ссылку документа - платформе уже надо опять лезть в документ, кроме таблицы табличной части. А если не делать отбор в табличной части - что он потянет? Всю таблицу?
50 RomanYS
 
20.12.19
14:57
(49) просто попробуй в (45) "ГДЕ" заменить на "И" и покажи замер
51 Кодер
 
20.12.19
15:00
Тебе надо постоянно вычислять список акций текущего магазина, или достаточно раз в сутки его вычислить, а всю смену получать готовый список?
52 Double_Medved
 
20.12.19
15:03
(48)
1. Там уже в документе дохренища вариантов этих акций, условий и т.д. Может и нужно будет
2. Ну это да, но в тестовой базе я один сижу, то есть она больше сейчас ничем не нагружена.

Потом как установлю - могу для интереса провести тесты еще на боевой базе, под нагрузкой. Наверняка будет медленней.

3. В данном случае нужна конкретная дата, да.


Наверняка потом нужны будут отчеты некие и т.д., может потребоваться период.
53 Double_Medved
 
20.12.19
15:03
(50) 0,16 секунд
54 Double_Medved
 
20.12.19
15:06
(51)Нужно много раз в день. Поступают некие документы типа "Заказ" и нужно высчитывать какие там скидки и т.д.

Можно было бы и раз в сутки чтото высчитывать, но всякие маркетологи могут влезть и поправить, поменять, запустить новую акцию с обеда и т.д., так что всегда надо получать точный список
55 dk
 
20.12.19
15:08
а если в самый быстрый вариант добавить Первые 1
56 Fragster
 
гуру
20.12.19
15:11
(52) зато на рабочей базе кэш горячий
57 RomanYS
 
20.12.19
15:15
(53) Значит явное соединение плюсов не дает. Можно ещё попробовать сначала выбрать в ВТ документы с нужными периодами, а потом соединить с ТЧ.

(25) Тебя результат с регистром не устраивает? Зачем дальнейшие поиски?
58 Double_Medved
 
20.12.19
15:41
(55)Акций в магазине может быть несколько (штук 10 например), нужны все, для дальнейших расчетов
59 Double_Medved
 
20.12.19
15:43
(57)Кстати с явным соединением вообще все плохо.

Как-то писали в 1С, что "рекомендуем использовать временные таблицы" или чет такое.

И сам замечал много раз, что использование временных таблиц в соединениях практически всегда дает повышение производительности, хотя по идее на помещение данных во временную таблицу уходит и время и память, но все равно быстрее получается
60 Double_Medved
 
20.12.19
15:44
(57)

Ищу истину.
61 RomanYS
 
20.12.19
15:48
(60) Ну пока что ты нашел - регистр быстрее.
Осталось понять тормоза из-за соединения или из-за индексов регистра.

Проверить соединение довольно просто - засунуть даты в ТЧ, соединение не понадобится. По крайней мере пока не надо будет проверять проведенность документа) - для теста пойдет
62 RomanYS
 
20.12.19
15:51
(59) Что значит "вообще все плохо" - результат же такой же.
В твоем случае объем ВТ будет явно меньше исходных таблиц, поэтому эффект может быть положительным
63 arsik
 
гуру
20.12.19
15:51
(60) Индексы учего есть?
1) Акции.ДатаН
2) Акции.ДатаК
3) АкцииАкцииПокупатели.ТорговаяТочка
64 Double_Medved
 
20.12.19
16:00
(63)
Так, стопе

В документе ничего не индексировалось, включил индексацию ДатаН, ДатаК, ТорговаяТочка - запрос к документам стал выполняться 0,07 сек

То есть раз в 20 быстрее.

Ничего не понимаю.

Неужели все волшебство в индексах? Чем это чревато может быть?
65 Double_Medved
 
20.12.19
16:01
(64)Тьфу, не в 20 раз, а в 2 раза.
66 Кодер
 
20.12.19
16:04
Когда ты первый раз выполняешь запрос, он выполняется медленно. Следующие разы - быстро. Почти как неравенство Шрёдингера.
67 timurhv
 
20.12.19
16:05
(0) Может бред, но регистр накопления (остаток):
+ Дата1, Магазин, Акция, 1
- Дата2, Магазин, Акция, 1
68 timurhv
 
20.12.19
16:14
(67) А лучше РСВ по позиции регистратора, т.к. акция же может корректироваться после утверждения и даты поменяться?
Магазин, Акция, Событие +, в ресурсах Дата1.
Магазин, Акция, Событие -, в ресурсах Дата2.
2 + 2 = 3.9999999999999999999999999999999...