Вход | Регистрация
    1  2
1С:Предприятие :: 1С:Предприятие 8 общая

Проблема со скоростью выполнения запроса

Проблема со скоростью выполнения запроса
Я
   Tester
 
03.05.19 - 16:34
Всем привет. Может кто подскажет почему один и тот же запрос, получающий выборку данных из временных таблиц с одним и тем же количеством записей чаще выполняется около 5 секунд, но иногда зависает на 1-2 часа?

Выбрать
                        втОтбор.Номенклатура,
                        втОтбор.Размещение,
                        втОтбор.СтруктурнаяЕдиница
                    Из
                        вт_ТаблицаОтбораЛокальная как втОтбор
                            ВНУТРЕННЕЕ СОЕДИНЕНИЕ вт_Родословная_Номенклатура КАК вт_Родословная_Номенклатура
                                ПО вт_Родословная_Номенклатура.ссылка = втОтбор.Номенклатура
                            ВНУТРЕННЕЕ СОЕДИНЕНИЕ вт_Родословная_Размещение КАК вт_Родословная_Размещение
                                ПО вт_Родословная_Размещение.ссылка = втОтбор.Размещение
                            ВНУТРЕННЕЕ СОЕДИНЕНИЕ вт_Родословная_СтруктурнаяЕдиница КАК вт_Родословная_СтруктурнаяЕдиница
                                ПО вт_Родословная_СтруктурнаяЕдиница.ссылка = втОтбор.СтруктурнаяЕдиница
                        Внутреннее соединение втОтборПредковПоЗначениям КАК втРодители
                            По вт_Родословная_Номенклатура.Предок = втРодители.НоменклатураПредок
                                И вт_Родословная_Размещение.Предок = втРодители.РазмещениеПредок
                                И вт_Родословная_СтруктурнаяЕдиница.Предок = втРодители.Структурная_единицаПредок
                    Сгруппировать по
                        втОтбор.Номенклатура,
                        втОтбор.Размещение,
                        втОтбор.СтруктурнаяЕдиница
 
 
   H A D G E H O G s
 
101 - 12.05.19 - 17:50
(100) Ставлю на mdop=0
   H A D G E H O G s
 
102 - 12.05.19 - 17:50
Ну или на tablespool
   rphosts
 
103 - 12.05.19 - 17:53
(101) нууу, ну вряд-ли тут параллельность так всё ломает.
(102) это вероятнее, но хз, хотя 1 диск на всё...

Автор, а там диск или хотя-бы какой рэйд-массив?
   Tester
 
104 - 12.05.19 - 17:54
(99) уже отловил.
План:
https://a.radikal.ru/a10/1905/b5/216b5d3d91b7.png


Запрос:

INSERT INTO #tt246 WITH(TABLOCK) (_Q_000_F_000RRef, _Q_000_F_001RRef, _Q_000_F_002_TYPE, _Q_000_F_002_RTRef, _Q_000_F_002_RRRef, _Q_000_F_003_TYPE, _Q_000_F_003_RTRef, _Q_000_F_003_RRRef, _Q_000_F_004RRef, _Q_000_F_005RRef) SELECT DISTINCT
T1._Q_000_F_000RRef,
T2._Q_000_F_001RRef,
T1._Q_000_F_001_TYPE,
T1._Q_000_F_001_RTRef,
T1._Q_000_F_001_RRRef,
T3._Q_000_F_001_TYPE,
T3._Q_000_F_001_RTRef,
T3._Q_000_F_001_RRRef,
T1._Q_000_F_002RRef,
T4._Q_000_F_001RRef
FROM #tt8 T1 WITH(NOLOCK)
INNER JOIN #tt55 T2 WITH(NOLOCK)
ON (T2._Q_000_F_000RRef = T1._Q_000_F_000RRef)
INNER JOIN #tt53 T3 WITH(NOLOCK)
ON (T3._Q_000_F_000_TYPE = T1._Q_000_F_001_TYPE AND T3._Q_000_F_000_RTRef = T1._Q_000_F_001_RTRef AND T3._Q_000_F_000_RRRef = T1._Q_000_F_001_RRRef)
INNER JOIN #tt47 T4 WITH(NOLOCK)
ON (T4._Q_000_F_000RRef = T1._Q_000_F_002RRef)
   rphosts
 
105 - 12.05.19 - 17:55
+ (103) скорее всего классика: старая статистика, большое расхождение между прогнозом и фактом и соответственно не тот способ соединения
   rphosts
 
106 - 12.05.19 - 17:55
(104) и есть 100500 способов его выполнения (ака планов выполнения этого самого запроса)
   H A D G E H O G s
 
107 - 12.05.19 - 17:56
(104) mdop=0
   H A D G E H O G s
 
108 - 12.05.19 - 17:57
   Tester
 
109 - 12.05.19 - 18:02
Max Degree of Parallelism = 0
   H A D G E H O G s
 
110 - 12.05.19 - 18:03
(109) Ставь =1, перезагружай SQL (но не уверен, что необходимо) и пробуй заново
   Провинциальный 1сник
 
111 - 12.05.19 - 18:08
(30) "а вообще засады в 8 часов с запросом - это обычно не чисто софтовая проблема, чаще всего это проблема ухода ОЗУ в своп"
С временными таблицами размером в единицы мегабайт? Какой тут своп. Тут нестедлуп в чистом виде. И бороться надо именно с ним.
   vde69
 
112 - 12.05.19 - 18:10
(110) при смене паралелизма требуется перезапуск службы
   vde69
 
113 - 12.05.19 - 18:13
из (104) видно, что довольно много времени занимает сортировка, а всего плана и не видно....
   H A D G E H O G s
 
114 - 12.05.19 - 18:13
(112) Не надо. Вот только что попробовал у себя.
   H A D G E H O G s
 
115 - 12.05.19 - 18:14
(113) Вставка в ВТ там половину времени.
   Tester
 
116 - 12.05.19 - 18:18
Ай, короче забейте пока. Этот запрос возвращает 85 млн строк :)
   H A D G E H O G s
 
117 - 12.05.19 - 18:20
(116) зачем тебе столько?
   vde69
 
118 - 12.05.19 - 18:23
(91) имено это я и предлогал....

заодно в вынесеном запросе второй джойн поставь третьим (где составной тип).

а вообще можно было-бы лучше спрогнозировать если ты в этом запросе дашь примерный результат по количеству

основная + первый ждойн
основная + второй джойн
основная + третий джойн

на основании этого можно подумать как именно собирать результат.

и еще
в SQL есть понятие что-то вроде плотности индекса (как точно не помню), в краце это некое отношение показывающее эффективность выборки, короче опиши для тех полей по которым джойнится сколько в среднем одинаковых значений в полях которые индексируешь, и примерное соотношение соеднинения

например на 1000 записей основной таблицы есть 10 записей вспомогательной, при этом соответсвий всего 2 (два уникальных значения, но записей отбираем 10), при этом мы должны понимать, что в результат попадет не 10 записей а немного больше :), собственно я скорее ставку в сабже сделаю именно на этот вариант..... (так сказать неявное умножение)
   vde69
 
119 - 12.05.19 - 18:25
(116) судя по всему я в (118) прав :)
   vde69
 
120 - 12.05.19 - 18:30
а стабильность в 3 минуты ты получил по тому, что ВТ неяным образом удаляет дубли, то есть потратил время на удаление из этих 67 лямов почти всего :)
   rphosts
 
121 - 12.05.19 - 18:31
(109) МЛЯ!!!!
   vde69
 
122 - 12.05.19 - 18:31
кстати вопрос Дмитрию:

при создании ВТ удаляются дубли или происходит свертка?
   rphosts
 
123 - 12.05.19 - 18:33
(122) только если создаешь с гроупбай или с безповторяющихся. просто так только кошки....
   rphosts
 
124 - 12.05.19 - 18:34
+ (121) настраивавшему сервер по рукам линейкой... металлической!
   rphosts
 
125 - 12.05.19 - 18:34
+ (123) хотя у Димы может другая версия
   H A D G E H O G s
 
126 - 12.05.19 - 18:36
(122) Ниче не удаляется и не свертывается, что отправилось в ВТ, то и будет в ВТ.
   H A D G E H O G s
 
127 - 12.05.19 - 18:39
(124) Я пока не видел ни одного клиента, у которого был бы настроен SQL полностью по заветам ИТС.
   rphosts
 
128 - 12.05.19 - 18:42
(127) у меня настроено... кое что не гуманно к лиц, но чуть-чуть, но там по другому никак.... ибо что за хрень местами в 1С (например покури внешние источники если субд не сиквел)
   vde69
 
129 - 12.05.19 - 18:54
по поводу составных типов:

мы видели, что составной тип в сабже был оттранслирован в условие с несколькими или, а теперь читаем ИТС

https://its.1c.ru/db/content/metod8dev/src/developers/scalability/standards/i8105842.htm?_=1557240526#or

Использование логического ИЛИ в условиях
Рекомендации
Использование логического ИЛИ в секции ГДЕ запроса
Не следует использовать ИЛИ в секции ГДЕ запроса. Это может привести к тому, что СУБД не сможет использовать индексы таблиц и будет выполнять сканирование, что увеличит время работы запроса и вероянтность возникновения блокировок. Вместо этого следует разбить один запрос на несколько и объединить результаты.

Например, запрос
ВЫБРАТЬ Товар.Наименование ИЗ Справочник.Товары КАК Товар ГДЕ Артикул = "001" ИЛИ Артикул = "002"

следует заменить на запрос

ВЫБРАТЬ Товар.Наименование ИЗ Справочник.Товары КАК Товар ГДЕ Артикул = "001"
 |ОБЪЕДИНИТЬ ВСЕ
 |ВЫБРАТЬ Товар.Наименование ИЗ Справочник.Товары КАК Товар ГДЕ Артикул = "002"
   Tester
 
130 - 12.05.19 - 19:50
(129) спс, с этим сталкивался лично. Разница в скорости выполнения отличалась в разы.
 
 Рекламное место пустует
   nicxxx
 
131 - 13.05.19 - 05:18
(32) Ты серьезно???
https://docs.microsoft.com/ru-ru/sql/t-sql/queries/search-condition-transact-sql?view=sql-server-2017
"Порядок выполнения логических операторов может меняться в зависимости от настроек оптимизатора запросов."
   zwolf
 
132 - 13.05.19 - 06:45
(131) Он пытается рассказать о двух вещах сразу - о селективности индекса в зависимости от порядка его полей и о покрывающих индексах. Ну, как может (:
   nicxxx
 
133 - 20.05.19 - 17:42
Вот, нашел где важен порядок. Table hint INDEX(). "The order of the indexes in the index hint is significant." (https://docs.microsoft.com/en-us/sql/t-sql/queries/hints-transact-sql-table?view=sql-server-2017)
   rphosts
 
134 - 20.05.19 - 18:58
(133) из 1С нет возможности передать подсказку оптимизатору.
   H A D G E H O G s
 
135 - 20.05.19 - 19:01
(129) Хороший пример, когда разбивать на несколько запросов по ИЛИ бессмысленно.
   nicxxx
 
136 - 21.05.19 - 05:54
(134) Это лишь ответ на странную фразу vde69 про порядок условий в секции WHERE.
   Nikoss
 
137 - 21.05.19 - 14:45
(135) зачем тогда этот пример написан в ИТС?
   nicxxx
 
138 - 24.05.19 - 11:15
(137) Затем, что это всего лишь пример. Когда структура отбора будет чуть сложней, чем (Артикул = "001" ИЛИ Артикул = "002"), тогда UNION ALL может очень пригодиться. Например, если у тебя там составное поле из нескольких документов, миллион строк и разброс данных очень значительный, а надо найди десяток документов двух видов. Через "ИЛИ" индекс скан будет длиться 60 секунд, а index seek + UNION ALL - 2 секунды.
   Tester
 
139 - 29.05.19 - 14:39
В общем решил проблему переписыванием запроса.
Доказательств, к сожалению, что SQL Server действительно строил неоптимальный план найти не удалось, т.к. подвисания были в нескольких процентах случаев, а в остальных запрос выполнялся пару секунд. Помог вынос результата части запроса во временные таблицы. Оборачивание в подзапрос несколько улучшало ситуацию (подвисания были реже), но все равно были.
  1  2

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