Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Оптимизация запроса / 20 сообщений из 20, страница 1 из 1
22.05.2018, 15:23
    #39648164
JohnAl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
Помогите гуру. Что то подкинул бизнес задачку...
Запрос:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
SELECT  TA.UNIQ, SA.STOREID, CONVERT(date, SA.DB, 4) AS DOC_DATE, SA.CASHCODE, SA.SHIFT
       ,TA.CHECKNUM, TA.BCODE, TA.ARTICUL
       ,TA.VATRATE1, TA.VATCODE1, va.NAME as VATCODENAME
       ,SUM(TA.VATSUM1 * OP.[SIGN]) AS VATSUM1 
       ,SUM(TA.BQUANT  * OP.[SIGN]) AS QTY_SUM
          ,SUM(TA.BQUANT * TA.PRICE * OP.[SIGN]) AS SUM_1
          ,SUM(TA.SUMB * OP.[SIGN]) AS SUMI
FROM dbo.ACS AS SA 
INNER JOIN  dbo.ACT AS TA 
       ON TA.CSID  = SA.UNIQ
INNER JOIN  dbo.OP AS OP 
       ON TA.OPCODE = OP.OPCODE
LEFT JOIN  dbo.VAT AS VA
       on VA.CODE = TA.VATCODE1
WHERE  (SA.DB >=  CONVERT(date,DATEADD(DAY, -3, getdate())) AND   SA.DB  < CONVERT(date, GETDATE())) 
AND   SA.STOREID > 3
GROUP BY  TA.UNIQ, SA.STOREID, CONVERT(date, SA.DB, 4), SA.CASHCODE, SA.SHIFT
         ,TA.CHECKNUM, TA.BCODE, TA.ARTICUL
         ,TA.VATRATE1, TA.VATCODE1, va.NAME;



Таблицы ACS, OP и VAT - маленькие. Таблица ACT - большая, более 1.3млрд записей. Задача выбрать данные по ней за 3 дня, ну от текущей даты скажем. Почему то происходит Table Scan этой большой таблицы ACT, хотя по идее - не должно. Этот скан, разумеется, дико замедляет запрос, перебрать миллиард записей то...
Куда рыть, не совсем понимаю, оптимизатор говорит про неоптимальный Hash Match, дескать Probe Residual, неявное преобразование и т.д. Но то неважно, соединить тысячи строк, это же не миллиард перебрать...
План запроса больше 150 кб, залил на гугл диск: https://drive.google.com/open?id=17wE-6Dtu-g_ehTgAk3SiWucVj1DgLXRF
...
Рейтинг: 0 / 0
22.05.2018, 15:28
    #39648167
Maxx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
отбери во времянку с ACT все подходящее под твое условие
WHERE (SA.DB >= CONVERT(date,DATEADD(DAY, -3, getdate())) AND SA.DB < CONVERT(date, GETDATE()))
AND SA.STOREID > 3
вот ето все обьяви в переменную до выборки
CONVERT(date,DATEADD(DAY, -3, getdate()))

,а уж патом джойнь и группируй

ЗЫ план не читал не дотсупен
...
Рейтинг: 0 / 0
22.05.2018, 15:38
    #39648172
982183
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
Возьми MIN(SA.UNIQ) с правильными датами, а потом выбери все TA с CSID большим чем она.
...
Рейтинг: 0 / 0
22.05.2018, 16:00
    #39648186
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
JohnAlПочему то происходит Table Scan этой большой таблицы ACTПотому что hast match и таблица на внутреннем входе.
Индекс нужен подходящий для dbo.ACT
...
Рейтинг: 0 / 0
22.05.2018, 16:06
    #39648190
JohnAl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
Maxx, план расшарил.
А почему в переменную, в чем тут тайный смысл?
WHERE то работает по маленькой таблице
...
Рейтинг: 0 / 0
22.05.2018, 16:07
    #39648192
JohnAl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
invm, индексы для ACT есть по полю CSID и по полю UNIQ. Но оба - некластеризованные
...
Рейтинг: 0 / 0
22.05.2018, 16:13
    #39648197
vborets
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
JohnAl,

В АСТ есть дата? фильтруй по ней в джойне
...
Рейтинг: 0 / 0
22.05.2018, 16:29
    #39648211
JohnAl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
vborets, не вариант
Грубо схема. ACS - заголовок документа, ACT - строки документа. Поле даты в ACT есть, но строк в ACT 1,3млрд, в ACS - пару млн. Фильтровать выгодней в ACS...
...
Рейтинг: 0 / 0
22.05.2018, 16:32
    #39648216
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
JohnAlinvm, индексы для ACT есть по полю CSID и по полю UNIQ. Но оба - некластеризованныеДля начала статистику обновите. Желательно с fullscan.
...
Рейтинг: 0 / 0
22.05.2018, 16:33
    #39648220
TaPaK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
JohnAlvborets, не вариант
Грубо схема. ACS - заголовок документа, ACT - строки документа. Поле даты в ACT есть, но строк в ACT 1,3млрд, в ACS - пару млн. Фильтровать выгодней в ACS...
invm ответил почему.
ваши
авториндексы для ACT есть по полю CSID и по полю UNIQ. Но оба - некластеризованные
не нравятся. Можете прибить по UNIQ но получите лукап
...
Рейтинг: 0 / 0
22.05.2018, 16:53
    #39648226
SFlash
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
Нужен индекс по ACT.CSID + хинт FORCESEEK (часто оптимизатор даже при нормальном индексе делает SCAN по индексу).
Но т.к. данных выбирается всего за 3 дня, лучше ему это указать явно.
...
Рейтинг: 0 / 0
22.05.2018, 17:28
    #39648259
JohnAl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
Ну так то автоматическая статистика обновляется в 16м скл неплохо... Статистику по индексам, да, давненько не обновлял...
...
Рейтинг: 0 / 0
23.05.2018, 10:15
    #39648472
JohnAl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
Ну и да, в итоге банальное устаревание статистики по индексу. Пересчитал частично за ночь с фулскан, план запроса сразу поменялся, индекс заработал.
Ох тыж, как бы еще придумать, чтобы за ночь обновление статистики проходило, а то ведь по одной этой большой таблице это почти на сутки, а по всей БД - двое...
Наверное стоит использовать sp_updatestats? Конечно, как там сервер решит, кто достоин обновления, вопрос, но работает быстрее. Или же, при ребилде индексов, статистика ведь тоже обновляется. Тогда выходит, выгодней ребилд индексов делать по отдельным таблицам.
...
Рейтинг: 0 / 0
23.05.2018, 10:17
    #39648476
TaPaK
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
JohnAl,

а auto update не включен что ли?
...
Рейтинг: 0 / 0
23.05.2018, 10:52
    #39648507
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
JohnAlОх тыж, как бы еще придумать, чтобы за ночь обновление статистики проходилоВозможно вам поможет секционирование и инкрементальное обновноление статистики.
JohnAlТогда выходит, выгодней ребилд индексов делать по отдельным таблицам.Одумайтесь.
...
Рейтинг: 0 / 0
23.05.2018, 22:21
    #39649040
Mind
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
JohnAlvborets, не вариант
Грубо схема. ACS - заголовок документа, ACT - строки документа. Поле даты в ACT есть, но строк в ACT 1,3млрд, в ACS - пару млн. Фильтровать выгодней в ACS...Бред! Коллега, вы не правы! Любые фильтры напрямую по огромным таблицам всегда лучше чем какие либо фильтры через джойны, потому что:
а) При джойне данные из большой таблицы дергаются по ID единичными index seek. В то время как BETWEEN фильтр по дате по основной таблицы пройдет в один seek по первой дате + scan до конечной даты, с полным префетчем и максимально возможной (учитывая фрагментацию) скоростью вычитки с диска.
б) Погрешности статистики при джойне всегда хуже чем при прямом фильтре. В 16ом конечно стало лучше, но до совершенства далеко.

Вы про это думаете что серверу нужно отфильровать лишние 1,3млрд минус 5 тысяч строк, и это куча работы, а должны думать как серверу нужно выбрать 5 тысяч строк по индексу и пофигу из таблицы какого размера. На самом деле даже если бы там было 100 млрд строк, то скорость выборки по индексу изменилась бы максимум на 1-2 дополнительных чтения или несколько миллисекунд. Для этого собственно индексы и нужны.
...
Рейтинг: 0 / 0
23.05.2018, 22:32
    #39649041
Mind
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
invmJohnAlТогда выходит, выгодней ребилд индексов делать по отдельным таблицам.Одумайтесь.Да можно и отдельные статистики с фуллсканом обновлять, в чем проблема то? Зачастую на таблице автоматом создается статистик как количество полей + индексов + если еще вручную кто сделал, большая часть из которых вообще никому не сдалась и зачем их все обновлять с фуллсканом? Каждая колоночная статистика это почти гарантированный table scan, в то время как индексная статистика это всего лишь index scan. Почти наверняка ТСу хватило бы обновить статистику по TA.CSID, SA.UNIQ, TA.OPCODE и OP.OPCODE. Там эстимейт выдает 227 миллионов строк при реальных 80.
...
Рейтинг: 0 / 0
24.05.2018, 02:46
    #39649095
982183
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
MindЛюбые фильтры напрямую по огромным таблицам всегда лучше чем какие либо фильтры через джойны, потому что:

Совершенно верно.
Именно поэтому я и предлагал сначала вывести из большой таблице некий дамп, а потом уже этот дамп джойнить.
...
Рейтинг: 0 / 0
24.05.2018, 09:28
    #39649164
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
MindДа можно и отдельные статистики с фуллсканом обновлять, в чем проблема то?Никаких.
Только ТС вместо этого хочет перестраивать индексы.
...
Рейтинг: 0 / 0
24.05.2018, 15:14
    #39649482
JohnAl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
Mindinvmпропущено...
Одумайтесь.Да можно и отдельные статистики с фуллсканом обновлять, в чем проблема то? Зачастую на таблице автоматом создается статистик как количество полей + индексов + если еще вручную кто сделал, большая часть из которых вообще никому не сдалась и зачем их все обновлять с фуллсканом? Каждая колоночная статистика это почти гарантированный table scan, в то время как индексная статистика это всего лишь index scan. Почти наверняка ТСу хватило бы обновить статистику по TA.CSID, SA.UNIQ, TA.OPCODE и OP.OPCODE. Там эстимейт выдает 227 миллионов строк при реальных 80.

Можно конечно. Просто вопрос автоматизации. Ручками выбрать статистики то - несложно, но таблиц в БД две сотни. Найду подходящий скрипт по апдейтам, тогда уж... Если кто подскажет, был бы благодарен.
А то вот нагуглил:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
DECLARE @DateNow DATETIME
SELECT @DateNow = DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()))

DECLARE @SQL NVARCHAR(MAX)
SELECT @SQL = (
    SELECT '
	UPDATE STATISTICS [' + SCHEMA_NAME(o.[schema_id]) + '].[' + o.name + '] [' + s.name + ']
		WITH FULLSCAN' + CASE WHEN s.no_recompute = 1 THEN ', NORECOMPUTE' ELSE '' END + ';'
	FROM (
		SELECT 
			  [object_id]
			, name
			, stats_id
			, no_recompute
			, last_update = STATS_DATE([object_id], stats_id)
		FROM sys.stats WITH(NOLOCK)
		WHERE auto_created = 0
			AND is_temporary = 0 -- 2012+
	) s
	JOIN sys.objects o WITH(NOLOCK) ON s.[object_id] = o.[object_id]
	JOIN (
		SELECT
			  p.[object_id]
			, p.index_id
			, total_pages = SUM(a.total_pages)
		FROM sys.partitions p WITH(NOLOCK)
		JOIN sys.allocation_units a WITH(NOLOCK) ON p.[partition_id] = a.container_id
		GROUP BY 
			  p.[object_id]
			, p.index_id
	) p ON o.[object_id] = p.[object_id] AND p.index_id = s.stats_id
	WHERE o.[type] IN ('U', 'V')
		AND o.is_ms_shipped = 0
		AND (
			  last_update IS NULL AND p.total_pages > 0 -- never updated and contains rows
			OR
			  last_update <= DATEADD(dd, 
				CASE WHEN p.total_pages > 4096 -- > 4 MB
					THEN -2 -- updated 3 days ago
					ELSE 0 
				END, @DateNow)
		)
    FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)')

PRINT @SQL
--EXEC sys.sp_executesql @SQL


А оно выводит не все таблицы (((

Фильтры хороши, но только когда есть индексы. В большой таблице АСТ индекса по дате - нет, есть только по id. Добавлять индексы в эту таблицу не особо возможно. Очень много интенсивной вставки данных, как пакетной так и нет. Чтения - намного меньше. Тут есть опасения, что накладные расходы от нового индекса превысят выгоды более быстрой работы отчета. На чтение, для отчетов, сделал снапшот с зеркала на другом сервере. Вот его терзают этими запросами. На боевой БД такие запросы - редкость, точнее стараемся их вывести на зеркальный сервер.
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Оптимизация запроса / 20 сообщений из 20, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]