powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Оптимизация запроса
20 сообщений из 20, страница 1 из 1
Оптимизация запроса
    #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
Оптимизация запроса
    #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
Оптимизация запроса
    #39648172
982183
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Возьми MIN(SA.UNIQ) с правильными датами, а потом выбери все TA с CSID большим чем она.
...
Рейтинг: 0 / 0
Оптимизация запроса
    #39648186
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JohnAlПочему то происходит Table Scan этой большой таблицы ACTПотому что hast match и таблица на внутреннем входе.
Индекс нужен подходящий для dbo.ACT
...
Рейтинг: 0 / 0
Оптимизация запроса
    #39648190
JohnAl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maxx, план расшарил.
А почему в переменную, в чем тут тайный смысл?
WHERE то работает по маленькой таблице
...
Рейтинг: 0 / 0
Оптимизация запроса
    #39648192
JohnAl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm, индексы для ACT есть по полю CSID и по полю UNIQ. Но оба - некластеризованные
...
Рейтинг: 0 / 0
Оптимизация запроса
    #39648197
vborets
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JohnAl,

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

а auto update не включен что ли?
...
Рейтинг: 0 / 0
Оптимизация запроса
    #39648507
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JohnAlОх тыж, как бы еще придумать, чтобы за ночь обновление статистики проходилоВозможно вам поможет секционирование и инкрементальное обновноление статистики.
JohnAlТогда выходит, выгодней ребилд индексов делать по отдельным таблицам.Одумайтесь.
...
Рейтинг: 0 / 0
Оптимизация запроса
    #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
Оптимизация запроса
    #39649041
Фотография Mind
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invmJohnAlТогда выходит, выгодней ребилд индексов делать по отдельным таблицам.Одумайтесь.Да можно и отдельные статистики с фуллсканом обновлять, в чем проблема то? Зачастую на таблице автоматом создается статистик как количество полей + индексов + если еще вручную кто сделал, большая часть из которых вообще никому не сдалась и зачем их все обновлять с фуллсканом? Каждая колоночная статистика это почти гарантированный table scan, в то время как индексная статистика это всего лишь index scan. Почти наверняка ТСу хватило бы обновить статистику по TA.CSID, SA.UNIQ, TA.OPCODE и OP.OPCODE. Там эстимейт выдает 227 миллионов строк при реальных 80.
...
Рейтинг: 0 / 0
Оптимизация запроса
    #39649095
982183
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MindЛюбые фильтры напрямую по огромным таблицам всегда лучше чем какие либо фильтры через джойны, потому что:

Совершенно верно.
Именно поэтому я и предлагал сначала вывести из большой таблице некий дамп, а потом уже этот дамп джойнить.
...
Рейтинг: 0 / 0
Оптимизация запроса
    #39649164
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MindДа можно и отдельные статистики с фуллсканом обновлять, в чем проблема то?Никаких.
Только ТС вместо этого хочет перестраивать индексы.
...
Рейтинг: 0 / 0
Оптимизация запроса
    #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
20 сообщений из 20, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Оптимизация запроса
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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