Вход | Регистрация



1С 8.3 Запрос. Меняешь одну секунду - в 30 раз дольше выполняется

1С 8.3 Запрос. Меняешь одну секунду - в 30 раз дольше выполняется
Я
   S_Scorp
 
18.10.18 - 14:40
Всем привет! У нас УПП 1.3, старенькая переписанная. Платформа 8.3.10.2252
Есть запрос:

/////////////////////////////////////////////////////

ВЫБРАТЬ
    ВзаиморасчетыСПокупателямиПоДокументамРасчетовОстатки.ДокументРасчетовСКонтрагентом КАК ДокументРасчетовСКонтрагентом,
    
    ВзаиморасчетыСПокупателямиПоДокументамРасчетов.ДоговорКонтрагента
ИЗ
    РегистрНакопления.ВзаиморасчетыСПокупателямиПоДокументамРасчетов.Остатки(&Период, Контрагент = &Контрагент) КАК ВзаиморасчетыСПокупателямиПоДокументамРасчетовОстатки
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ВзаиморасчетыСПокупателямиПоДокументамРасчетов КАК ВзаиморасчетыСПокупателямиПоДокументамРасчетов
        ПО ВзаиморасчетыСПокупателямиПоДокументамРасчетовОстатки.ДокументРасчетовСКонтрагентом = ВзаиморасчетыСПокупателямиПоДокументамРасчетов.ДокументРасчетовСКонтрагентом
            И ВзаиморасчетыСПокупателямиПоДокументамРасчетовОстатки.Контрагент = ВзаиморасчетыСПокупателямиПоДокументамРасчетов.Контрагент
/////////////////////////////////////////////////////

Если в консоли запросов установить Период 30.09.2018 23:59:59, запрос строится 1сек. Если 01.10.2018 00:00:00, то запрос строится 30 секунд.

Как оптимизировать запрос я буду думать и это не то что я хочу здесь спросить. Я хочу спросить как такое возможно? Как одна секунда так радикально влияет на время выполнения запроса?
 
 
   Cool_Profi
 
1 - 18.10.18 - 14:41
Итоги по октябрь рассчитай..
   FIXXXL
 
2 - 18.10.18 - 14:44
(0) регистры слАвны итогами...
   Tonik992
 
3 - 18.10.18 - 14:45
Выдержка из ИТС:
Пусть период рассчитанных итогов равен 31.07.2004. Мы хотим получить остатки на 01.07.2004, 15.07.2004, 01.08.2004, 15.08.2004 и актуальные остатки.
Для случаев получения остатков на 01.07.2004, 01.08.2004 и актуальных остатков данные будут получены непосредственно из таблицы итогов. В случае получения остатков на 15.07.2004 сначала будут получены данные из таблицы итогов на момент времени 01.08.2004, так как это ближайший больший момент времени, на который посчитаны остатки, а затем будут обработаны данные из таблицы движений за период с 15.07.2004 по 31.07.2004 включительно. В случае получения остатков на 15.08.2004, ближайшим большим моментом времени, на который посчитаны остатки является момент актуальных остатков. Таким образом, для расчета остатков на 15.08.2004, будут получены актуальные итоги и обработаны данные таблицы движений начиная с 15.08.2004.
   Tonik992
 
4 - 18.10.18 - 14:49
(1) Итоги за октябрь? Зачем это делать, ведь это текущие итоги.
   Tonik992
 
5 - 18.10.18 - 14:50
(4) Пардон, неправильно увидел.
Но все равно расчет итогов по октябрь не имеет смысл
   Cool_Profi
 
6 - 18.10.18 - 14:51
(5) Уже попробовал?
   Tonik992
 
7 - 18.10.18 - 14:52
(6) А вы рекомендацию пробовали свою для случая автора?
   Cool_Profi
 
8 - 18.10.18 - 14:52
(7) Офкоз. Только у меня его базы нет, мне не видно, что где там и как считается.
   S_Scorp
 
9 - 18.10.18 - 15:01
Все понятно, итоги, итоги и.т.д. Но почему тогда:
30.09.2018 23:59:59 строится 1 сек
01.10.2018 00:00:00 строится 30 сек
01.10.2018 00:00:01 строится снова 1 сек

Статистика показывает, что удаленность периода от рассчитанных итогов не имеет значения. имеет значение лишь одна конкретная дата.
   YUN1
 
10 - 18.10.18 - 15:03
(9) Надо пересчитать итоги, и всё наладится.
 
 Рекламное место пустует
   S_Scorp
 
11 - 18.10.18 - 15:05
   S_Scorp
 
12 - 18.10.18 - 15:06
(10) А как посмотреть на какую дату сейчас рассчитаны итоги по интересующему регистру?
   S_Scorp
 
13 - 18.10.18 - 15:49
(3) Описанная мной ситуация, как раз показывает, что что-то с этим механизмом не так...
   S_Scorp
 
14 - 18.10.18 - 15:50
(3) особенно принимая во внимание -> (9)
   Cool_Profi
 
15 - 18.10.18 - 15:53
Есть один вариант разрешить спор - поймать запрос профилером и посмотреть на него.
Как мне кажется - 146% вопросов уйдут
   Cyberhawk
 
16 - 18.10.18 - 15:56
(3) Не ясно, как эта выдержка должна помочь автору, ведь в ней везде время нулевое, а у автора как раз на нулевом времени тормоза
   Tonik992
 
17 - 18.10.18 - 15:57
(12) "Операции" -> "Управление итогами"
   Tonik992
 
18 - 18.10.18 - 15:58
(16) Вот, вы сделали на основе (3) какие-то выводы, эти выводы и должны помочь дальше. -)
   Cyberhawk
 
19 - 18.10.18 - 16:00
Пади движений на конец квартала овердохера, вот и вся причина
   Tonik992
 
20 - 18.10.18 - 16:05
А вы время замеряете на чистый запрос без левого соединения, или же нет? Может проблема в другом месте

ВЫБРАТЬ
    ВзаиморасчетыСПокупателямиПоДокументамРасчетовОстатки.ДокументРасчетовСКонтрагентом КАК ДокументРасчетовСКонтрагентом,
    
    ВзаиморасчетыСПокупателямиПоДокументамРасчетов.ДоговорКонтрагента
ИЗ
    РегистрНакопления.ВзаиморасчетыСПокупателямиПоДокументамРасчетов.Остатки(&Период, Контрагент = &Контрагент) КАК ВзаиморасчетыСПокупателямиПоДокументамРасчетовОстатки
   S_Scorp
 
21 - 18.10.18 - 16:47
(20) без левого соединения быстро строится. Там даже наоборот, в случае с периодом 00:00:00 секунд, 16млс выполняется, а там где 00:00:01 30млс, т.е. дольше.
   S_Scorp
 
22 - 18.10.18 - 16:47
Вот что профайл показал:

/////////////////////////////////////////////////////////////////////////////////

Та где 00:00:01 - Быстрый запрос
/////////////////////////////////////////////////////////////////////////////////


exec sp_executesql N'

SELECT
T1.Fld28407_TYPE,
T1.Fld28407_RTRef,
T1.Fld28407_RRRef,
T5._Fld28406RRef


FROM
(SELECT
T2.Fld28407_TYPE AS Fld28407_TYPE,

T2.Fld28407_RTRef AS Fld28407_RTRef,

T2.Fld28407_RRRef AS Fld28407_RRRef,

T2.Fld28405RRef AS Fld28405RRef,

CAST(SUM(T2.Fld28409Balance_) AS NUMERIC(38, 8)) AS Fld28409Balance_,

CAST(SUM(T2.Fld28410Balance_) AS NUMERIC(38, 8)) AS Fld28410Balance_

FROM
(SELECT
T3._Fld28407_TYPE AS Fld28407_TYPE,

T3._Fld28407_RTRef AS Fld28407_RTRef,

T3._Fld28407_RRRef AS Fld28407_RRRef,

T3._Fld28405RRef AS Fld28405RRef,

CAST(SUM(T3._Fld28409) AS NUMERIC(33, 8)) AS Fld28409Balance_,

CAST(SUM(T3._Fld28410) AS NUMERIC(33, 8)) AS Fld28410Balance_

FROM
dbo._AccumRgT28411 T3 WITH(NOLOCK)

WHERE
T3._Period = P1
AND ((T3._Fld28405RRef = @P2))
AND (T3._Fld28409 <> @P3 OR T3._Fld28410 <> @P4)
AND (T3._Fld28409 <> @P5 OR T3._Fld28410 <> @P6)

GROUP BY
T3._Fld28407_TYPE,

T3._Fld28407_RTRef,

T3._Fld28407_RRRef,

T3._Fld28405RRef

HAVING
(CAST(SUM(T3._Fld28409) AS NUMERIC(33, 8))) <> 0.0 OR (CAST(SUM(T3._Fld28410) AS NUMERIC(33, 8))) <> 0.0

UNION ALL SELECT

T4._Fld28407_TYPE AS Fld28407_TYPE,

T4._Fld28407_RTRef AS Fld28407_RTRef,

T4._Fld28407_RRRef AS Fld28407_RRRef,

T4._Fld28405RRef AS Fld28405RRef,

CAST(CAST(SUM(CASE WHEN T4._RecordKind = 0.0 THEN -T4._Fld28409 ELSE T4._Fld28409 END) AS NUMERIC(27, 8)) AS NUMERIC(27, 2)) AS Fld28409Balance_,

CAST(CAST(SUM(CASE WHEN T4._RecordKind = 0.0 THEN -T4._Fld28410 ELSE T4._Fld28410 END) AS NUMERIC(27, 8)) AS NUMERIC(27, 2)) AS Fld28410Balance_

FROM
dbo._AccumRg28403 T4 WITH(NOLOCK)

WHERE
T4._Period >= @P7 AND T4._Period < @P8 AND T4._Active = 0x01
AND ((T4._Fld28405RRef = @P9))

GROUP BY 
T4._Fld28407_TYPE,

T4._Fld28407_RTRef,

T4._Fld28407_RRRef,

T4._Fld28405RRef

HAVING
(CAST(CAST(SUM(CASE WHEN T4._RecordKind = 0.0 THEN -T4._Fld28409 ELSE T4._Fld28409 END) AS NUMERIC(27, 8)) AS NUMERIC(27, 2))) <> 0.0
OR (CAST(CAST(SUM(CASE WHEN T4._RecordKind = 0.0 THEN -T4._Fld28410 ELSE T4._Fld28410 END) AS NUMERIC(27, 8)) AS NUMERIC(27, 2))) <> 0.0) T2

GROUP BY
T2.Fld28407_TYPE,

T2.Fld28407_RTRef,

T2.Fld28407_RRRef,

T2.Fld28405RRef

HAVING (CAST(SUM(T2.Fld28409Balance_) AS NUMERIC(38, 8))) <> 0.0 
OR (CAST(SUM(T2.Fld28410Balance_) AS NUMERIC(38, 8))) <> 0.0) T1

LEFT OUTER JOIN
dbo._AccumRg28403 T5 WITH(NOLOCK)

ON
((T1.Fld28407_TYPE = T5._Fld28407_TYPE
AND T1.Fld28407_RTRef = T5._Fld28407_RTRef 
AND T1.Fld28407_RRRef = T5._Fld28407_RRRef) 
AND (T1.Fld28405RRef = T5._Fld28405RRef))

',N'P1 datetime2(3),@P2 varbinary(16),@P3 numeric(10),@P4 numeric(10),@P5 numeric(10),@P6 numeric(10),@P7 datetime2(3),@P8 datetime2(3),@P9 varbinary(16)','5999-11-01 00:00:00',0xAC80E931C065665A49E06FCB67FD7D00,0,0,0,0,'4018-10-01 00:00:01','5999-11-01 00:00:00',0xAC80E931C065665A49E06FCB67FD7D00

exec sp_executesql N'
SELECT
T1.Fld28407_TYPE,
T1.Fld28407_RTRef,
T1.Fld28407_RRRef,
T3._Fld28406RRef



/////////////////////////////////////////////////////////////////////////////////

Та где 00:00:01 - Долгийзапрос
/////////////////////////////////////////////////////////////////////////////////


FROM
(SELECT
T2._Fld28407_TYPE AS Fld28407_TYPE,

T2._Fld28407_RTRef AS Fld28407_RTRef,

T2._Fld28407_RRRef AS Fld28407_RRRef,

T2._Fld28405RRef AS Fld28405RRef,

CAST(SUM(T2._Fld28409) AS NUMERIC(33, 8)) AS Fld28409Balance_,

CAST(SUM(T2._Fld28410) AS NUMERIC(33, 8)) AS Fld28410Balance_

FROM
dbo._AccumRgT28411 T2 WITH(NOLOCK)

WHERE
T2._Period = P1
AND ((T2._Fld28405RRef = @P2))
AND (T2._Fld28409 <> @P3 OR T2._Fld28410 <> @P4)
AND (T2._Fld28409 <> @P5 OR T2._Fld28410 <> @P6)

GROUP BY
T2._Fld28407_TYPE,

T2._Fld28407_RTRef,

T2._Fld28407_RRRef,

T2._Fld28405RRef

HAVING
(CAST(SUM(T2._Fld28409) AS NUMERIC(33, 8))) <> 0.0 OR (CAST(SUM(T2._Fld28410) AS NUMERIC(33, 8))) <> 0.0) T1


LEFT OUTER JOIN
dbo._AccumRg28403 T3 WITH(NOLOCK)


ON

((T1.Fld28407_TYPE = T3._Fld28407_TYPE
AND T1.Fld28407_RTRef = T3._Fld28407_RTRef 
AND T1.Fld28407_RRRef = T3._Fld28407_RRRef) 
AND (T1.Fld28405RRef = T3._Fld28405RRef))

',N'P1 datetime2(3),@P2 varbinary(16),@P3 numeric(10),@P4 numeric(10),@P5 numeric(10),@P6 numeric(10)','4018-10-01 00:00:00',0xAC80E931C065665A49E06FCB67FD7D00,0,0,0,0
   S_Scorp
 
23 - 18.10.18 - 16:49
В случае с Быстрым запросом (Период 00:00:01) он засунул в SQL большой запрос. В другом случае запрос передался в два раза меньше по объему текста. И это все из-за одной секунды??
   Tonik992
 
24 - 18.10.18 - 16:55
План запроса сможете скинуть? Текстовый. В каждом случае.
   Timon1405
 
25 - 18.10.18 - 17:12
(11) судя по скринам, у вас стоят ИР. ищите вкладку "запрос результата" там кнопка "трасса", он предложит настроить ТЖ с фильтром по вам. в идеале в копии базы
   ptiz
 
26 - 18.10.18 - 17:17
Если 00:00 - быстро, а 00:01 - медленно, то это как раз объяснимо.
Если наоборот - это странно, не верю.
   rsv
 
27 - 18.10.18 - 17:40
(0) если уж так глубоко копнули то возьмите распотрашенные запросы и выполните их студии.Распотрашенка несложная.Временных таблиц нет.Графический план все покажет.
   unregistered
 
28 - 18.10.18 - 18:28
(22)(23)

Профайл же четко и ясно показывает, что в первом случае (быстрый запрос) остатки берутся из текущих итогов (на дату 5999-11-01, с учетом смещения 2000 - 3999-11-01). Во втором случае (медленный запрос) остатки берутся из таблицы итогов за октябрь месяц (на дату 4018-10-01, с учетом смещения 2000 - 2018-10-01).

Таблица текущих итогов значительно меньше таблицы итогов по периодам. Соответственно и план запроса разный.

Как вариант - сократите таблицу итогов по периодам, уменьшив период хранения итогов. Главное меню - Все функции - Стандартные - Управление итогами - Нажать гиперссылку "Полные возможности" (если откроется в режиме "Часто используемые возможности") - Встать на строку с нужным регистром и нажать кнопку командной панели "Установить период итогов", в диалоговом окне настройки периода итогов указать минимальный хранимый период для регистра накопления.
Если отчеты за прошлые года по этому регистру смотрят редко, то можно указать минимальный период - начало 2018 года.
Таким образом итоги за прошлые периоды (раньше установленной минимальной даты) храниться не будут и таблица итогов по периодам сократиться. При попытке обращения к этому регистру за более ранние периоды система будет каждый раз рассчитывать остатки от минимального периода хранения назад в прошлое по первичным движениям.
   timurhv
 
29 - 18.10.18 - 21:49
Какое жуткое соединение да еще и по составному измерению ДокументРасчетовСКонтрагентом:
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ВзаиморасчетыСПокупателямиПоДокументамРасчетов КАК ВзаиморасчетыСПокупателямиПоДокументамРасчетов

Я бы во временную таблицу вытащил с отбором по контрагенту и потом ее соединял.
   organizm
 
30 - 18.10.18 - 22:00
нормальные православные запросы не могут составить, а еще и в профилер лезут...
правильно в (29) говорят, тут не надо быть гением в сиквела, чтобы понять, что говнозапрос.
   Borteg
 
31 - 19.10.18 - 08:09
(0) Проблема в том что у вас я думаю очень огромная таблица итогов. И скорей всего в ней есть много нулевых записей.

К сожалению не могу посмотреть упп, есть ли индекс по полю документ расчетов?
   Borteg
 
32 - 19.10.18 - 08:10
(29) соединение по составному полю никак не влияет на производительность
   Borteg
 
33 - 19.10.18 - 08:14
(0) Попробуйте 29, уменьшить вторую таблицу было бы очень неплохо. Наверное раз база старая, то размеры соответствующие
 
 
   S_Scorp
 
34 - 19.10.18 - 08:28
Тормозит именно на датах:

01.10.2018 00:00:00
01.10.2018 00:00:00
01.10.2018 00:00:00
   S_Scorp
 
35 - 19.10.18 - 08:30
Тормозит именно на датах:

01.10.2018 00:00:00
01.09.2018 00:00:00
01.08.2018 00:00:00
и.т.д.

Я уже понял что запрос тут ни при чем и нужно изучать таблицу итогов.
   Borteg
 
36 - 19.10.18 - 08:30
(34) нужны планы запросов.
   S_Scorp
 
37 - 19.10.18 - 08:32
(31) по полю документ расчетов нет индексов
   S_Scorp
 
38 - 19.10.18 - 08:34
(36) сначала мне нужно погуглить что это и как их получить)
   Borteg
 
39 - 19.10.18 - 08:45
(38) тут скорее вся проблема описана в (28). В одном случае итоги текущие, в другом итог из таблицы итогов по месяцу. Тебе надо обойти эту ситуацию
   S_Scorp
 
40 - 19.10.18 - 08:56
(39) Все равно остается масса вопросов. Например, если взять просто запрос по остаткам, то период не влияет на скорость. Вообще никак. По крайней мере я этого не заметил. Но если использовать с соединением, то начинается жопа. Причем параметр Период я меняю в таблице остатков, а не в детальных записях регистра (что видно из запроса).
   Сияющий в темноте
 
41 - 19.10.18 - 09:42
Записи из регистра выберите,очень похоже,что на 01-хх-20хх у вас дофига записей,и с ними делается левое соединение,а во всех остальных случаях этого нет.
Можнл попробовать сначала выбрать остатки во временную таблицу,выкинуть нулевые записи,а потом соединяться,но лучше тоже с временной таблицей,проиндексированной по этим полям.
   Сияющий в темноте
 
42 - 19.10.18 - 09:44
и,кстати,при запросе на дату,отличную от даты итогов,запрос итак строится по временной таблице,откуда все нулевые записи выкидывает механизм построения,а при совпадении даты,в запрос просто копируется вся таблица итогов без удаления нулевых записей.
   timurhv
 
43 - 19.10.18 - 09:49
(32) судя по профайлеру запрос нам выложили неполный. Скорее всего составное поле не индексируется, либо на стороне sql устаревшая статистика и индексы, база должным образом не обслуживается. Поможет отбор реальной таблицы регистра накопления по контрагенту, помещение во временную таблицу и потом ее уже соединять. Либо уже разбираться с sql.
   timurhv
 
44 - 19.10.18 - 10:05
Ещё забыл, в соединении должны быть измерения, которые находятся выше контрагента в регистре если смотреть порядок в структуре, иначе ни о каких индексах не может быть речи
   Tonik992
 
45 - 19.10.18 - 10:07
(29) А что плохого в том, что соединение по полю составного типа? Разименование нет (не используется реквизит составного типа), поэтому тут всё четко. Даже сгенерированный запрос об этом говорит.
   S_Scorp
 
46 - 19.10.18 - 10:30
Спасибо за советы, я сейчас все проверю
   S_Scorp
 
47 - 19.10.18 - 10:30
Вот что еще заметил. У меня в таблице итогов есть 50+ тысяч записей с периодом 5999-11-01. Я так понял это текущие остатки. При этом из них только около 5 тысяч имеют ресурсы (т.е. сумма >0). Остальные хранятся с нулевыми суммами. Это нормально?
   Cyberhawk
 
48 - 19.10.18 - 10:33
(44) "в соединении должны быть измерения, которые находятся выше контрагента в регистре если смотреть порядок в структуре, иначе ни о каких индексах не может быть речи" // Если у измерения стоит флажок "Индексировать", то значит есть индекс где это измерение первое и ничего в запрос добавлять не нужно
   Cyberhawk
 
49 - 19.10.18 - 10:34
(47) Это норма. Сделай пересчет итогов или грохни таблицу итогов вручную - создастся новая без нулевых записей
 
 Рекламное место пустует
   timurhv
 
50 - 19.10.18 - 11:10
(48) Согласен, все нюансы тут не опишешь.
Подброно со всеми нюансами автору можно почитать тут:
https://its.1c.ru/db/metod8dev#content:5842:hdoc
   S_Scorp
 
51 - 19.10.18 - 12:12
(50) весьма признателен!


Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Рекламное место пустует