powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Как добиться partition elimination в запросе?
7 сообщений из 7, страница 1 из 1
Как добиться partition elimination в запросе?
    #39979873
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Коллеги, приветствую!
Вот такая проблем:
Имеется секционированная таблица, точнее, две секционированные таблицы, в разных схемах. Необходимо перебросить записи из одной таблицы в другую:
Код: sql
1.
2.
3.
4.
5.
6.
INSERT INTO [load].[ZAP]
SELECT a.*
FROM [act].[ZAP] a WITH (NOLOCK)
INNER JOIN #act b ON a.regstamp = b.regstamp
	AND a.ID_ACT = b.ID_ACT
OPTION (recompile, QUERYTRACEON 8649)


Таблицы секционированы по полю regstamp и имеют кластерный индекс по ID_ZAP, regstamp, и имеют некластерный индекс по ID_ACT, regstamp (который, соответственно, тоже секционирован).
В темповой таблице, соответственно, имеются 2 поля, ID_ACT и regstamp, которые используются как критерий для переноса
Код: sql
1.
Create table #act ([regstamp] int,  [ID_ACT] uniqueidentifier, primary key clustered([regstamp], [ID_ACT]));


Но, в актуальном плане запроса я не наблюдаю ничего похожего на partition elimination.
Собственно, вопросы:
1. Можно ли этого добиться?
2. Как этого добиться?
...
Рейтинг: 0 / 0
Как добиться partition elimination в запросе?
    #39979877
Гавриленко Сергей Алексеевич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А что в плане наблюдаете?
...
Рейтинг: 0 / 0
Как добиться partition elimination в запросе?
    #39979947
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Гавриленко Сергей Алексеевич, многопоточное сканирование индекса [regstamp], [ID_ACT] и потом кейлукап недостающих полей.
Причем при скане Number of Rows read = миллионы, при том, что в секциях должны быть сотни записей.
...
Рейтинг: 0 / 0
Как добиться partition elimination в запросе?
    #39979951
msLex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uaggster
Гавриленко Сергей Алексеевич, многопоточное сканирование индекса [regstamp], [ID_ACT] и потом кейлукап недостающих полей.
Причем при скане Number of Rows read = миллионы, при том, что в секциях должны быть сотни записей.

Ну так откуда SQL Server знает, данные из каких секций брать, если он сканирует [act].[ZAP].


Варианты на вскидку.

1. Сделать forceseek на [act].[ZAP], тогда на каждую запись из #act будет index seek + keylookup
2. Выбрать уникальные значения regstamp из #act, и через cross apply пройтись по каждому из них

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
SELECT a.*
FROM (
	SELECT DISTINCT regstamp
	from #act
) r
CROSS APPLY (
	SELECT a.*
	FROM [act].[ZAP] a WITH (NOLOCK)
	INNER JOIN #act b ON a.regstamp = b.regstamp
		AND a.ID_ACT = b.ID_ACT
	where 
		a.regstamp = r.regstamp
                and b.regstamp = r.regstamp 
) a
OPTION (recompile, QUERYTRACEON 8649)



В зависимости от количества записей и уникальных regstamp в #act то или иное решение может быть быстрее исходного сканирования всей таблицы [act].[ZAP]
...
Рейтинг: 0 / 0
Как добиться partition elimination в запросе?
    #39979974
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
msLex

Ну так откуда SQL Server знает, данные из каких секций брать, если он сканирует [act].[ZAP].

Не понимаю. [act].[ZAP] - тоже секционирована и тоже порезана на секции.

msLex
1. Сделать forceseek на [act].[ZAP], тогда на каждую запись из #act будет index seek + keylookup

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
INSERT INTO [load].[ZAP]
SELECT a.*
FROM [act].[ZAP] a WITH (NOLOCK, FORCESEEK)
INNER JOIN #act b ON a.regstamp = b.regstamp 
	AND a.ID_ACT = b.ID_ACT 
OPTION (
	RECOMPILE
	,QUERYTRACEON 8649
	)


Так план выглядит более адекватно.
Но в #act - в пределе десятки тысяч записей, а в [act].[ZAP] - десятки (сотни) миллионов.

Попробую, спасибо!
...
Рейтинг: 0 / 0
Как добиться partition elimination в запросе?
    #39979988
msLex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uaggster
msLex

Ну так откуда SQL Server знает, данные из каких секций брать, если он сканирует [act].[ZAP].

Не понимаю. [act].[ZAP] - тоже секционирована и тоже порезана на секции.


Для того, чтобы сделать partition elimination на [act].[ZAP] sql server нужно знать, к каким regstamp нужно будет обращаться.
Информация для этого есть только в #act.
Для её использования можно

1. Делать partition elimination относительно каждой записи в #act (вариант 1 с forceseek)
2. Собрать все уникальные regstamp из #act и сделать partition elimination по 1 одному разу на каждый их них (вариант с cross apply)
3. Выбрать max min regstamp из #act и добавить фильтр по диапазону a.regstamp between min_regstamp and max_regstamp. Но это вариант будет работать только в случае, если все regstamp из #act лежат в нескольких, подряд идущих секциях.
...
Рейтинг: 0 / 0
Как добиться partition elimination в запросе?
    #39980238
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
msLex, спасибо!
Вариант с FORCE_SEEK, как минимум, не ухудшил ситуацию.
...
Рейтинг: 0 / 0
7 сообщений из 7, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Как добиться partition elimination в запросе?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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