Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 SQL 2008, какой индекс создать чтобы выполнялся Index seek вместо Scan?  [new]
Pvase
Member

Откуда:
Сообщений: 1010
Пытаюсь оптимизировать запрос, наткнулся на таблицу _1SJOURN, что SQL не хочет делать seek по индексу.
Вот часть запроса к таблице, по которой создается индекс:
LEFT OUTER JOIN _1SJOURN AS Сорт_Счет WITH (NOLOCK) ON (Сорт_Счет.IDDOC = TMP.Счет)
а потом еще делается сортировка:
ORDER BY
	TMP.ТМЦ,
	Сорт_Счет.DATE_TIME_IDDOC,
Сделал для таблицы _1SJOURN индекс:
CREATE UNIQUE NONCLUSTERED INDEX [IX_Journ_DTID] ON [dbo].[_1SJOURN] 
(
	[IDDOC] ASC,
	[DATE_TIME_IDDOC] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
Индекс используется, но все равно продолжает делать Index Scan. Подскажите как можно исправить?
10 авг 11, 22:51    [11100790]     Ответить | Цитировать Сообщить модератору
 Re: SQL 2008, какой индекс создать чтобы выполнялся Index seek вместо Scan?  [new]
Pvase
Member

Откуда:
Сообщений: 1010
Прикладываю план выполнения, а также весь запрос:
+
if exists(select * from tempdb..sysobjects where id = object_id('tempdb..#TMP_MX'))
            drop table #TMP_MX
            create table #TMP_MX (val char(9) collate database_default, isfolder tinyint, primary key clustered (val))
insert #TMP_MX values ('     ACB ', 2)
insert #TMP_MX values ('     1   ', 2)
insert #TMP_MX values ('    24   ', 2)

if exists(select * from tempdb..sysobjects where id = object_id('tempdb..#TMP_TMC'))
            drop table #TMP_TMC
            create table #TMP_TMC (val char(9) collate database_default, isfolder tinyint, primary key clustered (val))
            
 insert #TMP_TMC values ('   7I9   ', 2)
 insert #TMP_TMC values ('   57F   ', 2)
 insert #TMP_TMC values ('   703   ', 2)
 insert #TMP_TMC values ('   9CF   ', 2)
 insert #TMP_TMC values ('   91R   ', 2)
 insert #TMP_TMC values ('   6T1   ', 2)
 insert #TMP_TMC values ('   9ET   ', 2)

 -- Итоги_РасширенныеОстаткиТоваров:
Declare @PERIODR DateTime
Declare @PERIODN Char(8)
Declare @PERIODK Char(23)
SET @PERIODR = Convert(DateTime,'20110701',112)
SET @PERIODN = '20110801'
SET @PERIODK = '201108087WRMN4  RIA9   '

SELECT
	TMP.Счет As [Счет $Документ.Счет],
	TMP.ТМЦ As [ТМЦ $Справочник.ТМЦ],
	TMP.МестоХранения As [МестоХранения $Справочник.МестаХранения],
	TMP.МестоРазмещения As [МестоРазмещения $Справочник.МестаРазмещения],
	TMP.Бухта As [Бухта $Справочник.Бухты],
	TMP.Производитель As [Производитель $Справочник.ПроизводителиМеталла],
	TMP.ДокументЗаказа As [ДокументЗаказа $Документ],
	TMP.Партия As [Партия $Справочник.СодержаниеБрака],
	TMP.ОстатокТовара As [ОстатокТовара],
	TMP.ОстатокУпаковок As [ОстатокУпаковок]
FROM (
SELECT

	TMP2.Счет As [Счет],
	TMP2.ТМЦ As [ТМЦ],
	TMP2.МестоХранения As [МестоХранения],
	TMP2.МестоРазмещения As [МестоРазмещения],
	TMP2.Бухта As [Бухта],
	TMP2.Производитель As [Производитель],
	TMP2.ДокументЗаказа As [ДокументЗаказа],
	TMP2.Партия As [Партия],
	SUM(TMP2.ОстатокТовара) As [ОстатокТовара],
	SUM(TMP2.ОстатокУпаковок) As [ОстатокУпаковок]
FROM (
SELECT
	TabR1.sp16782 AS Счет,
	TabR1.sp16282 AS ТМЦ,
	TabR1.sp16283 AS МестоХранения,
	TabR1.sp16285 AS МестоРазмещения,
	TabR1.sp16286 AS Бухта,
	TabR1.sp17201 AS Производитель,
	TabR1.sp18302 AS ДокументЗаказа,
	TabR1.sp18365 AS Партия,
	TabR1.sp16287 AS ОстатокТовара,
	TabR1.sp17202 AS ОстатокУпаковок
FROM 
	rg16288 AS TabR1 WITH (NOLOCK)
WHERE 
	TabR1.PERIOD = @PERIODR
	AND (TabR1.sp16282  IN (SELECT VAL FROM #TMP_TMC))
	AND (TabR1.sp16283  IN (SELECT VAL FROM #TMP_MX))
	
UNION ALL
SELECT
	TabR2.sp16782 AS Счет,
	TabR2.sp16282 AS ТМЦ,
	TabR2.sp16283 AS МестоХранения,
	TabR2.sp16285 AS МестоРазмещения,
	TabR2.sp16286 AS Бухта,
	TabR2.sp17201 AS Производитель,
	TabR2.sp18302 AS ДокументЗаказа,
	TabR2.sp18365 AS Партия,
	(TabR2.sp16287*((TabR2.DEBKRED+1)%2))- (TabR2.sp16287*TabR2.DEBKRED) AS ОстатокТовара,
	(TabR2.sp17202*((TabR2.DEBKRED+1)%2))- (TabR2.sp17202*TabR2.DEBKRED) AS ОстатокУпаковок
FROM 
	ra16288 AS TabR2 WITH (NOLOCK)
INNER JOIN _1SJOURN As TabJ WITH (NOLOCK) ON (TabR2.IDDOC = TabJ.IDDOC)
WHERE
	TabJ.DATE_TIME_IDDOC >= @PERIODN
	AND TabJ.DATE_TIME_IDDOC < @PERIODK
	AND (TabR2.sp16282  IN (SELECT VAL FROM #TMP_TMC))
	AND (TabR2.sp16283  IN (SELECT VAL FROM #TMP_MX))
	
      ) AS TMP2
GROUP BY 
	
	TMP2.Счет,
	TMP2.ТМЦ,
	TMP2.МестоХранения,
	TMP2.МестоРазмещения,
	TMP2.Бухта,
	TMP2.Производитель,
	TMP2.ДокументЗаказа,
	TMP2.Партия

HAVING
	(
	(SUM(TMP2.ОстатокТовара) <> 0)
	OR (SUM(TMP2.ОстатокУпаковок) <> 0))
		) AS TMP

LEFT OUTER JOIN _1SJOURN AS Сорт_Счет WITH (NOLOCK) ON (Сорт_Счет.IDDOC = TMP.Счет)
LEFT OUTER JOIN _1SJOURN AS Сорт_ДокументЗаказа WITH (NOLOCK) ON (Сорт_ДокументЗаказа.IDDOC = TMP.ДокументЗаказа)
ORDER BY
	TMP.ТМЦ,
	Сорт_Счет.DATE_TIME_IDDOC,
	TMP.МестоХранения,
	TMP.МестоРазмещения,
	TMP.Бухта,
	TMP.Производитель,
	Сорт_ДокументЗаказа.DATE_TIME_IDDOC,
	TMP.Партия


К сообщению приложен файл (123.rar - 7Kb) cкачать
10 авг 11, 23:43    [11100940]     Ответить | Цитировать Сообщить модератору
 Re: SQL 2008, какой индекс создать чтобы выполнялся Index seek вместо Scan?  [new]
aleks2
Guest
Pvase
Пытаюсь оптимизировать запрос, наткнулся на таблицу _1SJOURN, что SQL не хочет делать seek по индексу.
Подскажите как можно исправить?


1. Если вы выгребаете ВСЮ таблицу или ее большую часть - seek-а не будет никогда.
2. Если нада быстрее - пользуем временные таблицы.
11 авг 11, 08:38    [11101561]     Ответить | Цитировать Сообщить модератору
 Re: SQL 2008, какой индекс создать чтобы выполнялся Index seek вместо Scan?  [new]
Pvase
Member

Откуда:
Сообщений: 1010
aleks2
Pvase
Пытаюсь оптимизировать запрос, наткнулся на таблицу _1SJOURN, что SQL не хочет делать seek по индексу.
Подскажите как можно исправить?


1. Если вы выгребаете ВСЮ таблицу или ее большую часть - seek-а не будет никогда.
2. Если нада быстрее - пользуем временные таблицы.


Если использовать временную таблицу - работает. Но появляется другая проблема, временная таблица тоже должна быть проиндексирована, если в ней много строк.
Можно ли сделать
SELECT
...
INTO #TMP

а потом наложить индексы на эту временную таблицу? SQL 2008 это позволяет, а главное он будет их использовать?
11 авг 11, 09:26    [11101694]     Ответить | Цитировать Сообщить модератору
 Re: SQL 2008, какой индекс создать чтобы выполнялся Index seek вместо Scan?  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
Pvase
...а потом наложить индексы на эту временную таблицу? SQL 2008 это позволяет, а главное он будет их использовать?
Ога, позволяет.
А вот использовать или нет - зависит от запроса/ов.
11 авг 11, 09:29    [11101703]     Ответить | Цитировать Сообщить модератору
 Re: SQL 2008, какой индекс создать чтобы выполнялся Index seek вместо Scan?  [new]
Pvase
Member

Откуда:
Сообщений: 1010
Проблема еще в том, что запрос выполняется около 10 000 - 50 000 за ночь, в результате чего может возникнуть проблема с созданием временных таблиц (замедление их создания).
11 авг 11, 10:53    [11102212]     Ответить | Цитировать Сообщить модератору
 Re: SQL 2008, какой индекс создать чтобы выполнялся Index seek вместо Scan?  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Pvase,

Ну вам же сказали. Что будет использоваться индекс или нет зависит от кол-ва выбираемых строк. Во первых, сам индекс должен быть достаточно селективен, во вторых, запрос долже получать из таблицы небольшую порцию данных. Небольшую относительно всего объема таблицы, тогда будет выгодно использовать поиск по индексу.

Из плана мало что видно, к тому же все русские названия имеют вид абракадабры, но это ладно, самое главное план-то оценочный, а не действительный, не видно реальное количество строк. Если у вас в действительном плане используется просмотр индекса и оценочное значение сильно больше реального кол-ва строк, то это повод задуматься. Если нет, то посмотрите, а выполняются ли приведенные выше условия чтобы вообще было выгодно использовать поиск по индексу.
11 авг 11, 11:30    [11102478]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить