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

Откуда:
Сообщений: 8
Вот такой ИНТЕКС

CREATE NONCLUSTERED INDEX [lsd_AR2287] ON [dbo].[_AccumRegTotals2287]
(
[_Period] ASC,
[_Fld2437] ASC,
[_Fld2275] 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]

-----Выполняем запрос-------------------------
SET SHOWPLAN_TEXT ON;
go
SELECT top 20
_AccumRegTotals2287._Fld2267RRef _Fld2267RRef,
_AccumRegTotals2287._Fld2269_TYPE _Fld2269_TYPE,
_AccumRegTotals2287._Fld2269_RTRef _Fld2269_RTRef,
_AccumRegTotals2287._Fld2269_RRRef _Fld2269_RRRef,
_AccumRegTotals2287._Fld2270RRef _Fld2270RRef,
_AccumRegTotals2287._Fld2272 _Fld2272,
_AccumRegTotals2287._Fld2437 _Fld2437Balance,
_AccumRegTotals2287._Fld2275 _Fld2275Balance
FROM
_AccumRegTotals2287 WITH(NOLOCK )
WHERE
_AccumRegTotals2287._Period = '3999-11-01 00:00:00' AND
(_AccumRegTotals2287._Fld2437 <> CAST(0 AS NUMERIC(1,0)) OR
_AccumRegTotals2287._Fld2275 <> CAST(0 AS NUMERIC(1,0)));
--
go
SET SHOWPLAN_TEXT Off;
go
-------------тот же запрос, но просим уже идти по ИНДЕКСУ--------------
SET SHOWPLAN_TEXT ON;
go
SELECT top 20
_AccumRegTotals2287._Fld2267RRef _Fld2267RRef,
_AccumRegTotals2287._Fld2269_TYPE _Fld2269_TYPE,
_AccumRegTotals2287._Fld2269_RTRef _Fld2269_RTRef,
_AccumRegTotals2287._Fld2269_RRRef _Fld2269_RRRef,
_AccumRegTotals2287._Fld2270RRef _Fld2270RRef,
_AccumRegTotals2287._Fld2272 _Fld2272,
_AccumRegTotals2287._Fld2437 _Fld2437Balance,
_AccumRegTotals2287._Fld2275 _Fld2275Balance
FROM
_AccumRegTotals2287 WITH(NOLOCK , index (lsd_AR2287))
WHERE
_AccumRegTotals2287._Period = '3999-11-01 00:00:00' AND
(_AccumRegTotals2287._Fld2437 <> CAST(0 AS NUMERIC(1,0)) OR
_AccumRegTotals2287._Fld2275 <> CAST(0 AS NUMERIC(1,0)))
go
SET SHOWPLAN_TEXT Off
go
--SET STATISTICS IO off
статистика 1
--Table '_AccumRegTotals2287'. Scan count 1, logical reads 81, physical reads 0, read-ahead reads 1631, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
статистика 2
--Table '_AccumRegTotals2287'. Scan count 1, logical reads 24, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

--DBCC FREEPROCCACHE не помогло
--DBCC -FREESYSTEMCACHE

Габариты таблицы

--sp_spaceused _AccumRegTotals2287
--name rows reserved data index_size unused
-- ----------- ------------------ ------------------ ------------------ ------------------
_AccumRegTotals2287 45799666 19763840 KB 9902912 KB 9859480 KB 1448 KB

/* Выбирает по умолчанию


StmtText
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|--Top(TOP EXPRESSION:((20)))
|--Table Scan(OBJECT:([ets_2].[dbo].[_AccumRegTotals2287]), WHERE:([ets_2].[dbo].[_AccumRegTotals2287].[_Period]='3999-11-01 00:00:00.000' AND ([ets_2].[dbo].[_AccumRegTotals2287].[_Fld2437]<>(0.) OR [ets_2].[dbo].[_AccumRegTotals2287].[_Fld2275]<>(


*/


/* теперь с хинтом

StmtText
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|--Top(TOP EXPRESSION:((20)))
|--Nested Loops(Inner Join, OUTER REFERENCES:([Bmk1000], [Expr1005]) WITH UNORDERED PREFETCH)
|--Index Seek(OBJECT:([ets_2].[dbo].[_AccumRegTotals2287].[lsd_AR2287]), SEEK:([ets_2].[dbo].[_AccumRegTotals2287].[_Period]='3999-11-01 00:00:00.000'), WHERE:([ets_2].[dbo].[_AccumRegTotals2287].[_Fld2437]<>(0.) OR [ets_2].[dbo].[_AccumRegTot
|--RID Lookup(OBJECT:([ets_2].[dbo].[_AccumRegTotals2287]), SEEK:([Bmk1000]=[Bmk1000]) LOOKUP ORDERED FORWARD)


*/

в другой базе создал таблицу на 15 000 записей
с тем же типом полей и логикой
как только создаю индекс сразу начинает его использовать,
независимо от порядка полей (переход или скан, но задействует)
top 20 чтоб лишнего не крутить- на проблему не влияет

Проблема:почему интерпритатору так нравится сканировать таблицу
запрос я не могу менять, но хочется оптимазить индексом
DBCC FREEPROCCACHE не помогло
5 окт 09, 16:36    [7743877]     Ответить | Цитировать Сообщить модератору
 Re: как отучить сканировать таблицу  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74927
Обратите внимание:

автор
Index Seek(OBJECT:([ets_2].[dbo].[_AccumRegTotals2287].[lsd_AR2287]), SEEK:([ets_2].[dbo].[_AccumRegTotals2287].[_Period]='3999-11-01 00:00:00.000'), WHERE:([ets_2].[dbo].[_AccumRegTotals2287].[_Fld2437]<>(0.) OR [ets_2].[dbo].[_AccumRegTot


Seek выполнятеся только по дате. Остальное условие будут вычисляться движком для каждой строки, удовлетворяющей тому, что указано в SEEK, ибо там неравенство и OR, что никак не "обыграть" поиском по индексу. Т.е. включение двух последних полей в индекс бессмыслено.

Видимо поэтому сервер решает, что проще просканить, чем высчитывать значение WHERE для каждой строки. Кстати, каков процент строк с [_Period]='3999-11-01 00:00:00.000'.?
5 окт 09, 17:02    [7744118]     Ответить | Цитировать Сообщить модератору
 Re: как отучить сканировать таблицу  [new]
lsd25
Member

Откуда:
Сообщений: 8
запрос правда корявый - согласен, но деваться некуда

для [_Period]='3999-11-01 00:00:00.000'
count() =2 426 342
всего в таблице 45 799 666
индекс по [_Period] то же не воспринимает

это самое обидное, возьми 2 милиона и ковыряй их
так он таблицу сканит

сердце кровью обливается от этого

обидно что на тесте в другой базе любому индексу рад

статистика есть, обновлял
5 окт 09, 17:16    [7744234]     Ответить | Цитировать Сообщить модератору
 Re: как отучить сканировать таблицу  [new]
Glory
Member

Откуда:
Сообщений: 104760
lsd25


это самое обидное, возьми 2 милиона и ковыряй их
так он таблицу сканит

сердце кровью обливается от этого

Два миллиона раз lookup - это нормально по-вашему ?
5 окт 09, 17:19    [7744256]     Ответить | Цитировать Сообщить модератору
 Re: как отучить сканировать таблицу  [new]
pkarklin
Member

Откуда: Москва (Муром)
Сообщений: 74927
автор
запрос правда корявый - согласен,


И без его изменения вряд ли что "улучшить".

автор
обидно что на тесте в другой базе любому индексу рад


Ну так на тесте в дургой базе у Вас "не те объемы".

Сообщение было отредактировано: 5 окт 09, 17:21
5 окт 09, 17:20    [7744263]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить