Доброго дня, коллеги.
Периодически смотрю статистику по индексам (sys.dm_db_missing_index)... и наткнулся на предложенный sql server'ом индекс по полю "КлючСвязи".
Открываю конфигурацию (УТ11) и вижу, что абсолютно все поля такого рода неиндексируемые, в роли значений там УИД.
Оказывается, что во всех типовых оно такое (смотрел и в ЕРП, и в БП и в Рознице...).
Вот пример типового запроса с этим полем:
Обратите внимание на "ВТ_ЗаданиеНаПеревозкуСтроки".
Главный прикол в том, что никакого скана нет! Но субд предлагает аж 2 индекса добавить, один из них по ключу связи.
В чем подвох?!
Ради интереса сделал замеры. Без индекса этот пакет выполняется 0.5 с, а с ним 0.35 с. (сделал update statistics _Document287_VT7698 with fullscan)
Записей в таблице "_Document287_VT7698" всего 113579.
Статистика IO:
Периодически смотрю статистику по индексам (sys.dm_db_missing_index)... и наткнулся на предложенный sql server'ом индекс по полю "КлючСвязи".
Открываю конфигурацию (УТ11) и вижу, что абсолютно все поля такого рода неиндексируемые, в роли значений там УИД.
Оказывается, что во всех типовых оно такое (смотрел и в ЕРП, и в БП и в Рознице...).
Вот пример типового запроса с этим полем:
// Подбирает из Заданий на перевозку значения последних реквизитов доставки по получателю или партнеру.
// Параметры:
// ПолучательОтправитель - СправочникСсылка.Партнеры, СправочникСсылка.Склады - необязательный, если указан Перевозчик,
// Перевозчик - СправочникСсылка.Партнеры - необязательный, если указан ПолучательОтправитель.
//
// Возвращаемое значение:
// ТаблицаЗначений - содержит три последних набора реквизитов доставки по Партнеру или Перевозчику.
// Колонки:
// АдресДоставки,
// АдресДоставкиЗначенияПолей,
// ЗонаДоставки,
// ВремяС,
// ВремяПо,
// ДополнительнаяИнформация.
//
Функция ПоследниеРеквизитыДоставкиИзЗаданий(ПолучательОтправитель = Неопределено, Перевозчик = Неопределено) Экспорт
ТекстЗапроса =
"ВЫБРАТЬ
| ЗаданиеНаПеревозкуРаспоряжения.НомерСтроки,
| ЗаданиеНаПеревозкуРаспоряжения.Ссылка.Дата,
| ЗаданиеНаПеревозкуРаспоряжения.КлючСвязи,
| ЗаданиеНаПеревозкуРаспоряжения.ВремяС,
| ЗаданиеНаПеревозкуРаспоряжения.ВремяПо,
| ЗаданиеНаПеревозкуРаспоряжения.ДополнительнаяИнформация,
| ЗаданиеНаПеревозкуМаршрут.Адрес,
| ЗаданиеНаПеревозкуМаршрут.АдресЗначенияПолей
|ПОМЕСТИТЬ ВТ_ЗаданиеНаПеревозкуСтроки
|ИЗ
| Документ.ЗаданиеНаПеревозку.Распоряжения КАК ЗаданиеНаПеревозкуРаспоряжения
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.ЗаданиеНаПеревозку.Маршрут КАК ЗаданиеНаПеревозкуМаршрут
| ПО (ЗаданиеНаПеревозкуМаршрут.КлючСвязи = ЗаданиеНаПеревозкуРаспоряжения.КлючСвязи)
|ГДЕ
| ЗаданиеНаПеревозкуРаспоряжения.Ссылка.Проведен
| И (ЗаданиеНаПеревозкуРаспоряжения.ПолучательОтправитель = &ПолучательОтправитель
| Или &ПолучательОтправитель = НЕОПРЕДЕЛЕНО)
| И (ЗаданиеНаПеревозкуРаспоряжения.Перевозчик = &Перевозчик
| Или &Перевозчик = НЕОПРЕДЕЛЕНО
| И ЗаданиеНаПеревозкуРаспоряжения.Перевозчик = ЗНАЧЕНИЕ(Справочник.Партнеры.ПустаяСсылка))
|;
|
|//////////////////////////////////////////////////////////// ////////////////////
|ВЫБРАТЬ ПЕРВЫЕ 3
| ВТ_ЗаданиеНаПеревозкуСтроки.Адрес КАК Адрес,
| МАКСИМУМ(ВТ_ЗаданиеНаПеревозкуСтроки.Дата) КАК Дата
|ПОМЕСТИТЬ ВТ_ПоследниеАдреса
|ИЗ
| ВТ_ЗаданиеНаПеревозкуСтроки КАК ВТ_ЗаданиеНаПеревозкуСтроки
|ГДЕ
| ВТ_ЗаданиеНаПеревозкуСтроки.Адрес <> """"
|
|СГРУППИРОВАТЬ ПО
| ВТ_ЗаданиеНаПеревозкуСтроки.Адрес
|
|УПОРЯДОЧИТЬ ПО
| МАКСИМУМ(ВТ_ЗаданиеНаПеревозкуСтроки.Дата) УБЫВ
|;
|
|//////////////////////////////////////////////////////////// ////////////////////
|ВЫБРАТЬ
| ВТ_ПоследниеАдреса.Адрес,
| ЗаданиеНаПеревозкуМаршрут.Зона,
| ЗаданиеНаПеревозкуМаршрут.Ссылка.Дата
|ПОМЕСТИТЬ ВТ_МаршрутыСНужнымиАдресами
|ИЗ
| ВТ_ПоследниеАдреса КАК ВТ_ПоследниеАдреса
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.ЗаданиеНаПеревозку.Маршрут КАК ЗаданиеНаПеревозкуМаршрут
| ПО ВТ_ПоследниеАдреса.Адрес = ЗаданиеНаПеревозкуМаршрут.Адрес
|ГДЕ
| ЗаданиеНаПеревозкуМаршрут.Ссылка.Проведен
|;
|
|//////////////////////////////////////////////////////////// ////////////////////
|ВЫБРАТЬ
| ВТ_ПоследниеАдреса.Адрес,
| МАКСИМУМ(ВТ_МаршрутыСНужнымиАдресами.Дата) КАК Дата
|ПОМЕСТИТЬ ВТ_ДатыПоследнихЗонПоАдресам
|ИЗ
| ВТ_ПоследниеАдреса КАК ВТ_ПоследниеАдреса
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_МаршрутыСНужнымиАдресами КАК ВТ_МаршрутыСНужнымиАдресами
| ПО ВТ_ПоследниеАдреса.Адрес = ВТ_МаршрутыСНужнымиАдресами.Адрес
|
|СГРУППИРОВАТЬ ПО
| ВТ_ПоследниеАдреса.Адрес
|;
|
|//////////////////////////////////////////////////////////// ////////////////////
|ВЫБРАТЬ
| МАКСИМУМ(ВТ_МаршрутыСНужнымиАдресами.Зона) КАК Зона,
| ВТ_ДатыПоследнихЗонПоАдресам.Адрес
|ПОМЕСТИТЬ ВТ_ПоследниеЗоныПоАдресам
|ИЗ
| ВТ_МаршрутыСНужнымиАдресами КАК ВТ_МаршрутыСНужнымиАдресами
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_ДатыПоследнихЗонПоАдресам КАК ВТ_ДатыПоследнихЗонПоАдресам
| ПО (ВТ_ДатыПоследнихЗонПоАдресам.Адрес = ВТ_МаршрутыСНужнымиАдресами.Адрес)
| И (ВТ_ДатыПоследнихЗонПоАдресам.Дата = ВТ_МаршрутыСНужнымиАдресами.Дата)
|
|СГРУППИРОВАТЬ ПО
| ВТ_ДатыПоследнихЗонПоАдресам.Адрес
|;
|
|//////////////////////////////////////////////////////////// ////////////////////
|ВЫБРАТЬ
| ВТ_ПоследниеАдреса.Адрес,
| МАКСИМУМ(ВТ_ЗаданиеНаПеревозкуСтроки.КлючСвязи) КАК КлючСвязи
|ПОМЕСТИТЬ ВТ_ПоследниеАдресаКлючиСвязи
|ИЗ
| ВТ_ПоследниеАдреса КАК ВТ_ПоследниеАдреса
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_ЗаданиеНаПеревозкуСтроки КАК ВТ_ЗаданиеНаПеревозкуСтроки
| ПО (ВТ_ЗаданиеНаПеревозкуСтроки.Адрес = ВТ_ПоследниеАдреса.Адрес)
| И (ВТ_ЗаданиеНаПеревозкуСтроки.Дата = ВТ_ПоследниеАдреса.Дата)
|
|СГРУППИРОВАТЬ ПО
| ВТ_ПоследниеАдреса.Адрес
|;
|
|//////////////////////////////////////////////////////////// ////////////////////
|ВЫБРАТЬ
| ВТ_ПоследниеАдресаКлючиСвязи.КлючСвязи,
| МАКСИМУМ(ВТ_ЗаданиеНаПеревозкуСтроки.НомерСтроки) КАК НомерСтроки
|ПОМЕСТИТЬ ВТ_ПоследниеАдресаКлючиСвязиНомераСтрок
|ИЗ
| ВТ_ПоследниеАдресаКлючиСвязи КАК ВТ_ПоследниеАдресаКлючиСвязи
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_ЗаданиеНаПеревозкуСтроки КАК ВТ_ЗаданиеНаПеревозкуСтроки
| ПО (ВТ_ЗаданиеНаПеревозкуСтроки.КлючСвязи = ВТ_ПоследниеАдресаКлючиСвязи.КлючСвязи)
|
|СГРУППИРОВАТЬ ПО
| ВТ_ПоследниеАдресаКлючиСвязи.Адрес,
| ВТ_ПоследниеАдресаКлючиСвязи.КлючСвязи
|;
|
|//////////////////////////////////////////////////////////// ////////////////////
|ВЫБРАТЬ
| ВТ_ЗаданиеНаПеревозкуСтроки.Адрес КАК АдресДоставки,
| ВТ_ЗаданиеНаПеревозкуСтроки.АдресЗначенияПолей КАК АдресДоставкиЗначенияПолей,
| ВТ_ПоследниеЗоныПоАдресам.Зона КАК ЗонаДоставки,
| ВТ_ЗаданиеНаПеревозкуСтроки.ВремяС КАК ВремяДоставкиС,
| ВТ_ЗаданиеНаПеревозкуСтроки.ВремяПо КАК ВремяДоставкиПо,
| ВТ_ЗаданиеНаПеревозкуСтроки.ДополнительнаяИнформация КАК ДополнительнаяИнформацияПоДоставке
|ИЗ
| ВТ_ЗаданиеНаПеревозкуСтроки КАК ВТ_ЗаданиеНаПеревозкуСтроки
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_ПоследниеАдресаКлючиСвязиНомераСтрок КАК ВТ_ПоследниеАдресаКлючиСвязиНомераСтрок
| ПО ВТ_ЗаданиеНаПеревозкуСтроки.КлючСвязи = ВТ_ПоследниеАдресаКлючиСвязиНомераСтрок.КлючСвязи
| И ВТ_ЗаданиеНаПеревозкуСтроки.НомерСтроки = ВТ_ПоследниеАдресаКлючиСвязиНомераСтрок.НомерСтроки
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_ПоследниеЗоныПоАдресам КАК ВТ_ПоследниеЗоныПоАдресам
| ПО (ВТ_ПоследниеЗоныПоАдресам.Адрес = ВТ_ЗаданиеНаПеревозкуСтроки.Адрес)
|
|УПОРЯДОЧИТЬ ПО
| ВТ_ЗаданиеНаПеревозкуСтроки.Дата УБЫВ";
Запрос = Новый Запрос(ТекстЗапроса);
Запрос.УстановитьПараметр("ПолучательОтправитель", ПолучательОтправитель);
Запрос.УстановитьПараметр("Перевозчик", Перевозчик);
УстановитьПривилегированныйРежим(Истина);
Результат = Запрос.Выполнить().Выгрузить();
УстановитьПривилегированныйРежим(Ложь);
Возврат Результат;
КонецФункции
ПоказатьОбратите внимание на "ВТ_ЗаданиеНаПеревозкуСтроки".
Главный прикол в том, что никакого скана нет! Но субд предлагает аж 2 индекса добавить, один из них по ключу связи.
В чем подвох?!
Ради интереса сделал замеры. Без индекса этот пакет выполняется 0.5 с, а с ним 0.35 с. (сделал update statistics _Document287_VT7698 with fullscan)
Записей в таблице "_Document287_VT7698" всего 113579.
Статистика IO:
(строк обработано: 433)
Таблица "Workfile". Число просмотров 0, логических чтений 0, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.
Таблица "Worktable". Число просмотров 0, логических чтений 0, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.
Таблица "_Document287_VT7698". Число просмотров 1, логических чтений 10157, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.
Таблица "_Document287". Число просмотров 0, логических чтений 1335, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.
Таблица "_Document287_VT7710". Число просмотров 1, логических чтений 4605, физических чтений 0, упреждающих чтений 0, lob логических чтений 0, lob физических чтений 0, lob упреждающих чтений 0.
(строк обработано: 1)
ПоказатьПрикрепленные файлы:
Ответы
Подписаться на ответы
Инфостарт бот
Сортировка:
Древо развёрнутое
Свернуть все
Текстовый план:
Rows Executes StmtText StmtId NodeId Parent PhysicalOp LogicalOp Argument DefinedValues EstimateRows EstimateIO EstimateCPU AvgRowSize TotalSubtreeCost OutputList Warnings Type Parallel EstimateExecutions
---- -------- -------- ------ ------ ------ ---------- --------- -------- ------------- ------------ ---------- ----------- ---------- ---------------- ---------- -------- ---- -------- ------------------
433 1 Hash Match(Inner Join, HASH:([T1].[_Fld7712])=([T2].[_Fld7706]), RESIDUAL:([__________ut_test].[dbo].[_Document287_VT7698].[_Fld7706] as [T2].[_Fld7706]=[__________ut_test].[dbo].[_Document287_VT7710].[_Fld7712] as [T1].[_Fld7712])) 0 0 Hash Match Inner Join HASH:([T1].[_Fld7712])=([T2].[_Fld7706]), RESIDUAL:([__________ut_test].[dbo].[_Document287_VT7698].[_Fld7706] as [T2].[_Fld7706]=[__________ut_test].[dbo].[_Document287_VT7710].[_Fld7712] as [T1].[_Fld7712]) 427,594 0 1,93556 8660 14,7319 [T1].[_LineNo7711], [T1].[_Fld7712], [T1].[_Fld7718], [T1].[_Fld7719], [T1].[_Fld7720], [T2].[_Fld7700], [T2].[_Fld7709], [T3].[_Date_Time] PLAN_ROW 0 1
433 1 |--Nested Loops(Inner Join, OUTER REFERENCES:([T1].[_Document287_IDRRef], [Expr1003]) WITH UNORDERED PREFETCH) 0 1 0 Nested Loops Inner Join OUTER REFERENCES:([T1].[_Document287_IDRRef], [Expr1003]) WITH UNORDERED PREFETCH 427,594 0 0,00179436 4132 5,18364 [T1].[_LineNo7711], [T1].[_Fld7712], [T1].[_Fld7718], [T1].[_Fld7719], [T1].[_Fld7720], [T3].[_Date_Time] PLAN_ROW 0 1
433 1 | |--Clustered Index Seek(OBJECT:([__________ut_test].[dbo].[_Document287_VT7710].[_Document287_VT7710_IntKeyInd] AS [T1]), SEEK:([T1].[_Fld706]=[@P2]), WHERE:([__________ut_test].[dbo].[_Document287_VT7710].[_Fld7717_RRRef] as [T1].[_Fld7717_RRRef]=[@P5] AND [__________ut_test].[dbo].[_Document287_VT7710].[_Fld7716RRef] as [T1].[_Fld7716RRef]=[@P8] AND [__________ut_test].[dbo].[_Document287_VT7710].[_Fld7717_TYPE] as [T1].[_Fld7717_TYPE]=0x08 AND [__________ut_test].[dbo].[_Document287_VT7710].[_Fld7717_RTRef] as [T1].[_Fld7717_RTRef]=0x0000009D AND [__________ut_test].[dbo].[_Document287_VT7710].[_Fld7717_S] as [T1].[_Fld7717_S]=[@P4]) ORDERED FORWARD) 0 3 1 Clustered Index Seek Clustered Index Seek OBJECT:([__________ut_test].[dbo].[_Document287_VT7710].[_Document287_VT7710_IntKeyInd] AS [T1]), SEEK:([T1].[_Fld706]=[@P2]), WHERE:([__________ut_test].[dbo].[_Document287_VT7710].[_Fld7717_RRRef] as [T1].[_Fld7717_RRRef]=[@P5] AND [__________ut_test].[dbo].[_Document287_VT7710].[_Fld7716RRef] as [T1].[_Fld7716RRef]=[@P8] AND [__________ut_test].[dbo].[_Document287_VT7710].[_Fld7717_TYPE] as [T1].[_Fld7717_TYPE]=0x08 AND [__________ut_test].[dbo].[_Document287_VT7710].[_Fld7717_RTRef] as [T1].[_Fld7717_RTRef]=0x0000009D AND [__________ut_test].[dbo].[_Document287_VT7710].[_Fld7717_S] as [T1].[_Fld7717_S]=[@P4]) ORDERED FORWARD [T1].[_Document287_IDRRef], [T1].[_LineNo7711], [T1].[_Fld7712], [T1].[_Fld7718], [T1].[_Fld7719], [T1].[_Fld7720] 429,272 3,39275 0,166264 4282 3,55902 [T1].[_Document287_IDRRef], [T1].[_LineNo7711], [T1].[_Fld7712], [T1].[_Fld7718], [T1].[_Fld7719], [T1].[_Fld7720] PLAN_ROW 0 1
433 433 | |--Clustered Index Seek(OBJECT:([__________ut_test].[dbo].[_Document287].[_Document287HPK] AS [T3]), SEEK:([T3].[_Fld706]=[@P1] AND [T3].[_IDRRef]=[__________ut_test].[dbo].[_Document287_VT7710].[_Document287_IDRRef] as [T1].[_Document287_IDRRef]), WHERE:([__________ut_test].[dbo].[_Document287].[_Posted] as [T3].[_Posted]=0x01) ORDERED FORWARD) 0 4 1 Clustered Index Seek Clustered Index Seek OBJECT:([__________ut_test].[dbo].[_Document287].[_Document287HPK] AS [T3]), SEEK:([T3].[_Fld706]=[@P1] AND [T3].[_IDRRef]=[__________ut_test].[dbo].[_Document287_VT7710].[_Document287_IDRRef] as [T1].[_Document287_IDRRef]), WHERE:([__________ut_test].[dbo].[_Document287].[_Posted] as [T3].[_Posted]=0x01) ORDERED FORWARD [T3].[_Date_Time] 1 0,003125 0,0001581 14 1,35383 [T3].[_Date_Time] PLAN_ROW 0 429,272
113579 1 |--Clustered Index Seek(OBJECT:([__________ut_test].[dbo].[_Document287_VT7698].[_Document287_VT7698_IntKeyInd] AS [T2]), SEEK:([T2].[_Fld706]=[@P3]) ORDERED FORWARD) 0 5 0 Clustered Index Seek Clustered Index Seek OBJECT:([__________ut_test].[dbo].[_Document287_VT7698].[_Document287_VT7698_IntKeyInd] AS [T2]), SEEK:([T2].[_Fld706]=[@P3]) ORDERED FORWARD [T2].[_Fld7700], [T2].[_Fld7706], [T2].[_Fld7709] 113579 7,48757 0,125094 4610 7,61266 [T2].[_Fld7700], [T2].[_Fld7706], [T2].[_Fld7709] PLAN_ROW 0 1
Показать
Ап. Снова наткнулся на этот типовой код, когда ТЖ анализировал.
При копировании заказа постоянно заполняются эти реквизиты доставки.
ТЖ:
Все-таки нужно оптимизировать запрос.
При копировании заказа постоянно заполняются эти реквизиты доставки.
ТЖ:
Система.ПолучитьФорму : Документ.ЗаказКлиента.ФормаОбъекта
Документ.ЗаказКлиента.Форма.ФормаДокумента.Форма : 128 : ПриЧтенииСозданииНаСервере();
Документ.ЗаказКлиента.Форма.ФормаДокумента.Форма : 4505 : ДоставкаТоваров.ПриЧтенииСозданииРаспоряженийНаСервере(Элементы, Объект);
ОбщийМодуль.ДоставкаТоваров.Модуль : 429 : ЗаполнитьСпискиВыбораАдресовПолучателяОтправителя(ЭлементыФормы, ДокОбъект);
ОбщийМодуль.ДоставкаТоваров.Модуль : 3024 : ПоследниеРеквизитыДоставкиИзЗаданий = ПоследниеРеквизитыДоставкиИзЗаданий(ПолучательОтправитель);
ОбщийМодуль.ДоставкаТоваров.Модуль : 888 : Результат = Запрос.Выполнить().Выгрузить();
ВремяВыполнения: 19 109 мс
Все-таки нужно оптимизировать запрос.
Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот