SQL не использует индексов!

chenosov
Дата: 10.12.2002 17:46:36
MS SQL 7 SP3

Имею таблицу (структуру упростил):

CREATE TABLE [dbo].[sklad] (
[id_sklad] [int] IDENTITY (1, 1) NOT NULL ,
[date] [smalldatetime] NOT NULL ,
[cods] [int] NOT NULL ,
[codtov] [int] NOT NULL ,
[sums] [decimal](15, 2) NOT NULL ,
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[sklad] WITH NOCHECK ADD
CONSTRAINT [PK_sklad] PRIMARY KEY NONCLUSTERED
(
[id_sklad]
) WITH FILLFACTOR = 90 ON [PRIMARY]
GO

CREATE INDEX [date] ON [dbo].[sklad]([date]) WITH FILLFACTOR = 90 ON
[PRIMARY]
GO

CREATE INDEX [cods] ON [dbo].[sklad]([cods]) WITH FILLFACTOR = 90 ON
[PRIMARY]
GO

CREATE INDEX [codtov] ON [dbo].[sklad]([codtov]) WITH FILLFACTOR = 90 ON
[PRIMARY]
GO

Табличка довольно значительная - около 10 млн. записей. Замечаю, что запросы
идут долго.
Делаю из QA несколько простых запросов:

select sum(sums) from sklad where date='09.01.2002' and cods in
(1341,1345,1358)
select date, sum(sums) from sklad where date='09.01.2002'
select sum(sums) from sklad where cods in (1341,1345,1358)


Смотрю план, только первый из запросов использует оба индекса! Остальные
сканируют таблицу.
Кто мне сможет объяснить, что нужно делать. Прямое подключение индексов
помогает. Что же везде ставить прямое указание индексов?
Update statistic не предлагать - не помогает!
jimmers
Дата: 10.12.2002 17:52:13
А как такое (select date, sum(sums) from sklad where date='09.01.2002') вообще компилируется?
dkstranger
Дата: 10.12.2002 17:53:12
2jimmers
Думаю, пропущено group by
chenosov
Дата: 10.12.2002 18:01:04
Пардон, это я уже пытался модифицировать запрос. На самом деле он выглядит ровно также:

select date, sum(sums) from sklad where date='09.01.2002'
chenosov
Дата: 10.12.2002 18:02:18
Тьфу, еще раз:
select sum(sums) from sklad where date='09.01.2002'
AAron
Дата: 10.12.2002 18:07:39
а если попробовать создать индекс на (date, cods) или (cods, date), что получится? кстати, чтобы индекс был покрывающим полезно добавить туда же еще и столбец sums. По крайней мере по мнению MS, покрывающий индекс способен значительно облегчить жизнь. сам не пробовал, объемы не те :))
Genady
Дата: 10.12.2002 18:12:42
2 chenosov
А самый простой вариант решения проблемы пробовали?
Взять свои запросы и скормить их ITW и построить те индексы, которые он посоветует.
VVG_
Дата: 10.12.2002 18:12:55
Ну за суммами то ему все равно в таблицу лезть. Вот он и считает, что сканирование таблицы побыстрее будет. Если сумму в индекс добавить - то залетает.

Посмотри в BOL/Creating and Maintaining Databases/Indexes/Designing an Index/Using Nonclustered Indexes.
chenosov
Дата: 10.12.2002 18:55:19
Господа!
Я довел пример до самого простейшего. В запросе:

select sum(sums) from sklad where date='09.01.2002'

указана колонка date, являющяяся единственным условием поиска. И она же является единственной в индексе! Какое же еще нужно указание оптимизатору? Но он индекс не использует, и запрос у меня работает больше 3 минут.
Если я в прямую указываю индекс:

select sum(sums) from sklad (index(date)) where date='09.01.2002'

То запрос работает меньше минуты.
Что касается указания в индексе еще и поля Sums, то это уже ни в какие ворота не лезет. Это поле нужно только для вычисления, но никак не для поиска.
VVG_
Дата: 10.12.2002 19:02:23
Что касается указания в индексе еще и поля Sums, то это уже ни в какие ворота не лезет. Это поле нужно только для вычисления, но никак не для поиска.

Уважаемый, если Вам надо оптимизировать запрос, то попробуйте сделать covered index (как рекомендовано в BOL) или указывайте явно хинт.

А думать о том, как и почему работает оптимизатор в MSSQL противопоказано местными докторами.