Имя: Пароль:
1C
1С v8
Снова про SQL, планы запроса 8.2 и 8.3. Условие Ссылка В(&МассивРазныхТипов)
0 ptiz
 
14.11.17
15:11
Хотим отказаться от режима совместимости 8.1, и перейти на 8.2 (по причине Спецам SQL. Тормоза в списке документов (обычные формы, 8.2, SQL) ) , но наткнулись на бяку.
(на 8.3 переходить - не вариант, много глюков словил сразу же - даже конфигуратор вылетает).


Простой код. И Запрос2 в нем работает очень по-разному.

    Запрос = Новый Запрос("ВЫБРАТЬ ПЕРВЫЕ 128    //127 - РАБОТАЕТ БЫСТРО!!!
                          |    РеализацияТоваров.Дата КАК Дата,
                          |    РеализацияТоваров.Ссылка
                          |ИЗ
                          |    Документ.РеализацияТоваров КАК РеализацияТоваров
                          |
                          |ОБЪЕДИНИТЬ ВСЕ
                          |
                          |ВЫБРАТЬ ПЕРВЫЕ 1
                          |    ПоступлениеТоваров.Дата,
                          |    ПоступлениеТоваров.Ссылка
                          |ИЗ
                          |    Документ.ПоступлениеТоваров КАК ПоступлениеТоваров
                          |");
    Массив = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка");
    Сообщить("Ок1");
    
    Запрос2 = Новый Запрос("ВЫБРАТЬ
                           |    РеализацияТоваров.Ссылка
                           |ИЗ
                           |    Документ.РеализацияТоваров КАК РеализацияТоваров
                           |ГДЕ
                           |    РеализацияТоваров.Ссылка В(&Массив)
                           |");
    Запрос2.УстановитьПараметр("Массив", Массив);
    
    Результат = Запрос2.Выполнить();
    
    Сообщить("Ок2");

    
    
Условие Ссылка В(&Массив) работает по-разному в случае составных типов в массиве.
Да, знаю, что это нехорошее условие, но прекрасно с этим жили до сих пор на 8.1. На внутреннее соединение переписывать все запросы - затратно.

Если элементов до 128, то текст выглядит так и всё летает во всех платформах:

SELECT
T1._IDRRef
FROM _Document240 T1 WITH(NOLOCK)
WHERE (T1._IDRRef IN (P1, @P2, @P3, @P4, @P5, @P6, @P7, @P8, @P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, @P20, @P21, @P22, @P23, @P24, @P25, @P26, @P27, @P28, @P29, @P30, @P31, @P32, @P33, @P34, @P35, @P36, @P37, @P38, @P39, @P40, @P41, @P42, @P43, @P44, @P45, @P46, @P47, @P48, @P49, @P50, @P51, @P52, @P53, @P54, @P55, @P56, @P57, @P58, @P59, @P60, @P61, @P62, @P63, @P64, @P65, @P66, @P67, @P68, @P69, @P70, @P71, @P72, @P73, @P74, @P75, @P76, @P77, @P78, @P79, @P80, @P81, @P82, @P83, @P84, @P85, @P86, @P87, @P88, @P89, @P90, @P91, @P92, @P93, @P94, @P95, @P96, @P97, @P98, @P99, P100, P101, P102, P103, P104, P105, P106, P107, P108, P109, P110, P111, P112, P113, P114, P115, P116, P117, P118, P119, P120, P121, P122, P123, P124, P125, P126, P127))


Если элементов больше 128 - начинаются фокусы.

Платформа 8.1 (или режим совместимости 8.1 в более поздних) - летает!
Запрос выглядит так:

SELECT
_Document240_Q_000_T_001._IDRRef AS f_1
FROM
_Document240 _Document240_Q_000_T_001 WITH(NOLOCK)
WHERE
_Document240_Q_000_T_001._IDRRef IN (SELECT p1 FROM #tt1)




Платформа 8.2.19 - без режима совместимости. Тормоза жуткие! (Таблица большая - миллионы документов)

SELECT
T1._IDRRef
FROM _Document240 T1 WITH(NOLOCK)
WHERE T1._IDRRef IN
(SELECT
CASE WHEN T2._INVALUELISTTRef = P1 THEN T2._INVALUELISTRRef ELSE 0xFF END AS INVALUELISTRRef
FROM #tt1 T2 WITH(NOLOCK)
WHERE CASE WHEN T2._INVALUELISTTRef = @P2 THEN T2._INVALUELISTRRef ELSE @P3 END IS NOT NULL)


План из профайлера:

StmtText                                                                                                                                                                                                                                                                          
--------                                                                                                                                                                                                                                                                          
Parallelism(Gather Streams)                                                                                                                                                                                                                                                        
  |--Nested Loops(Left Semi Join, WHERE:([test4_82].[dbo].[_Document240].[_IDRRef] as [T1].[_IDRRef]=CASE WHEN [tempdb].[dbo].[#tt1].[_INVALUELISTTRef] as [T2].[_INVALUELISTTRef]=[P1] THEN [tempdb].[dbo].[#tt1].[_INVALUELISTRRef] as [T2].[_INVALUELISTRRef] ELSE 0xFF END))
       |--Index Scan(OBJECT:([test4_82].[dbo].[_Document240].[_Documen240_ByField6525_LR] AS [T1]))                                                                                                                                                                              
       |--Table Spool                                                                                                                                                                                                                                                              
            |--Index Scan(OBJECT:([tempdb].[dbo].[#tt1] AS [T2]),  WHERE:(CASE WHEN [tempdb].[dbo].[#tt1].[_INVALUELISTTRef] as [T2].[_INVALUELISTTRef]=[@P2] THEN [tempdb].[dbo].[#tt1].[_INVALUELISTRRef] as [T2].[_INVALUELISTRRef] ELSE [@P3] END IS NOT NULL))                

            
План из техножурнала:
            
129, 1, 129, 0, 0.0287, 23, 51.6, 1,   |--Parallelism(Gather Streams)
129, 4, 129, 0, 27.9, 23, 51.5, 1,        |--Nested Loops(Left Semi Join, WHERE:([test4_82].[dbo].[_Document240].[_IDRRef] as [T1].[_IDRRef]=CASE WHEN [tempdb].[dbo].[#tt1].[_INVALUELISTTRef] as [T2].[_INVALUELISTTRef]=[P1] THEN [tempdb].[dbo].[#tt1].[_INVALUELISTRRef] as [T2].[_INVALUELISTRRef] ELSE 0xFF END))
102709, 4, 1.03E+005, 0.219, 0.0566, 23, 0.275, 1,             |--Index Scan(OBJECT:([test4_82].[dbo].[_Document240].[_Documen240_ByField6525_LR] AS [T1]))
13343785, 102709, 130, 0.01, 0.000124, 27, 12.7, 1.03E+005,             |--Table Spool
520, 4, 130, 0.00313, 0.0003, 27, 0.00343, 1,                  |--Index Scan(OBJECT:([tempdb].[dbo].[#tt1] AS [T2]),  WHERE:(CASE WHEN [tempdb].[dbo].[#tt1].[_INVALUELISTTRef] as [T2].[_INVALUELISTTRef]=[@P2] THEN [tempdb].[dbo].[#tt1].[_INVALUELISTRRef] as [T2].[_INVALUELISTRRef] ELSE [@P3] END IS NOT NULL))





Платформа 8.3.11 - режим совместимости 8.3.16. Летает! Хотя запрос идентичен 8.2


SELECT
T1._IDRRef
FROM dbo._Document240 T1 WITH(NOLOCK)
WHERE T1._IDRRef IN
(SELECT
CASE WHEN T2._INVALUELISTTRef = 0x000000F0 THEN T2._INVALUELISTRRef ELSE 0xFF END AS INVALUELISTRRef
FROM #tt1 T2 WITH(NOLOCK)
WHERE CASE WHEN T2._INVALUELISTTRef = 0x000000F0 THEN T2._INVALUELISTRRef ELSE ? END IS NOT NULL)
p_0: 0xFF


План из профайлера:

StmtText                                                                                                                                                                                                                                                                          
--------                                                                                                                                                                                                                                                                          
Sort(DISTINCT ORDER BY:([T1].[_IDRRef] ASC))                                                                                                                                                                                                                                      
  |--Nested Loops(Inner Join, OUTER REFERENCES:([Expr1006], [Expr1022]) WITH UNORDERED PREFETCH)                                                                                                                                                                                  
       |--Compute Scalar(DEFINE:([Expr1006]=CASE WHEN [tempdb].[dbo].[#tt1].[_INVALUELISTTRef] as [T2].[_INVALUELISTTRef]=0x000000F0 THEN [tempdb].[dbo].[#tt1].[_INVALUELISTRRef] as [T2].[_INVALUELISTRRef] ELSE 0xFF END))                                                    
       |    |--Clustered Index Scan(OBJECT:([tempdb].[dbo].[#tt1] AS [T2]), WHERE:(CASE WHEN [tempdb].[dbo].[#tt1].[_INVALUELISTTRef] as [T2].[_INVALUELISTTRef]=0x000000F0 THEN [tempdb].[dbo].[#tt1].[_INVALUELISTRRef] as [T2].[_INVALUELISTRRef] ELSE [P1] END IS NOT NULL))
       |--Clustered Index Seek(OBJECT:([test4_83].[dbo].[_Document240].[PK___Documen__AC8ED0C40A83538F] AS [T1]), SEEK:([T1].[_IDRRef]=[Expr1006]) ORDERED FORWARD)                                                                                                              

      
План из техножурнала:
      
129, 1, 129, 0.0113, 0.00151, 23, 0.438, 1,   |--Sort(DISTINCT ORDER BY:([T1].[_IDRRef] ASC))
129, 1, 129, 0, 0.000543, 23, 0.425, 1,        |--Nested Loops(Inner Join, OUTER REFERENCES:([Expr1006], [Expr1022]) WITH UNORDERED PREFETCH)
0, 0, 130, 0, 1.3E-005, 39, 0.00344, 1,             |--Compute Scalar(DEFINE:([Expr1006]=CASE WHEN [tempdb].[dbo].[#tt1].[_INVALUELISTTRef] as [T2].[_INVALUELISTTRef]=0x000000F0 THEN [tempdb].[dbo].[#tt1].[_INVALUELISTRRef] as [T2].[_INVALUELISTRRef] ELSE 0xFF END))
130, 1, 130, 0.00313, 0.0003, 27, 0.00343, 1,             |    |--Clustered Index Scan(OBJECT:([tempdb].[dbo].[#tt1] AS [T2]), WHERE:(CASE WHEN [tempdb].[dbo].[#tt1].[_INVALUELISTTRef] as [T2].[_INVALUELISTTRef]=0x000000F0 THEN [tempdb].[dbo].[#tt1].[_INVALUELISTRRef] as [T2].[_INVALUELISTRRef] ELSE [P1] END IS NOT NULL))
129, 130, 1, 0.00313, 0.000158, 23, 0.421, 130,             |--Clustered Index Seek(OBJECT:([test4_83].[dbo].[_Document240].[PK___Documen__AC8ED0C40A83538F] AS [T1]), SEEK:([T1].[_IDRRef]=[Expr1006]) ORDERED FORWARD)


Так влияют временные таблицы?

В 8.2 у временных таблиц такой индекс:
create index [TMPIND_0] on [#tt1] (_INVALUELISTTRef, _INVALUELISTRRef)

и вставка значений выглядит так:
StmtText                                                                                                                                                                                                                                                                                                  
--------                                                                                                                                                                                                                                                                                                  
Table Insert(OBJECT:([tempdb].[dbo].[#tt1]), OBJECT:([tempdb].[dbo].[#tt1]), SET:([tempdb].[dbo].[#tt1].[_INVALUELISTTRef] = [Expr1003],[tempdb].[dbo].[#tt1].[_INVALUELISTRRef] = [Expr1004]), DEFINE:([Expr1003]=CONVERT_IMPLICIT(binary(4),[P1],0), [Expr1004]=CONVERT_IMPLICIT(binary(16),[@P2],0)))


В 8.3 у временных таблиц Кластерный индекс:
CREATE CLUSTERED INDEX idx1 ON #tt1 (_INVALUELISTTRef, _INVALUELISTRRef)

и вставка значений выглядит так:
StmtText                                                                                                                                                                                                                                                                            
--------                                                                                                                                                                                                                                                                            
Clustered Index Insert(OBJECT:([tempdb].[dbo].[#tt1]), SET:([tempdb].[dbo].[#tt1].[_INVALUELISTTRef] = [Expr1003],[tempdb].[dbo].[#tt1].[_INVALUELISTRRef] = [Expr1004]), DEFINE:([Expr1003]=CONVERT_IMPLICIT(binary(4),[P1],0), [Expr1004]=CONVERT_IMPLICIT(binary(16),[@P2],0)))


SQL 2008. Пробовал на 2014 - тормоза те же. Базы 8.2 и 8.3 - обе загружены из dt (на боевой - та же фигня).

Можно что-то в SQL подкрутить, чтобы запрос 8.2 заработал с такой скоростью, как в 8.3?
1 Ёпрст
 
14.11.17
15:13
(0) забить на 8.2 перейти сразу на 8.3 без режима совместимости.
переписывать не так и много. В пару мест поставить заглушки + чутка форматнуть код (там где процы стали предопределенными).
Делов на полчаса.
2 ptiz
 
14.11.17
15:20
(1) После того, как в 8.3 получил вылеты даже в конфигураторе(!), желание переходить на неё сразу отпало.
3 Ёпрст
 
14.11.17
15:23
(2) нет там вылетов в конфигураторе.
Всего лишь нужно тексты модулей привести в соответствии с новой платформой.
4 Ёпрст
 
14.11.17
15:25
И..за одну только невозможность иметь фоновые задания во внешних обработках, надо задвинуть 8.1 в топку.
Ошибка? Это не ошибка, это системная функция.