|
|
|
Зачем сканировать таблицу
|
|||
|---|---|---|---|
|
#18+
Проблема такая: есть таблица платежей, по ней построен индекс по полям inn, doc_date даю команду: SELECT inn, annot FROM plt WHERE doc_date between '01.01.2002' AND '04.01.2002' число возвращенных записей - 29 в профилере duration = 40 в плане выполнения вижу, что сканируется мой индекс, а затем по нему отбираются нужные строки - все ОК НО!!! SELECT inn, annot FROM plt WHERE doc_date between '01.01.2002' AND '05.01.2002' число возвращенных записей - 33 в профилере duration = 170 в плане выполнения - сканирование ВСЕЙ таблицы с фильтром по дате теперь запускаем: SELECT inn, annot FROM plt (INDEX=plt0) WHERE doc_date between '01.01.2002' AND '05.01.2002' число возвращенных записей - 33 в профилере duration = 42 в плане выполнения - конечно сканирование индекса т.е. если к-во возвращаемых записей больше 30, то индекс не используется и запрос выполняется в четыре раза дольше!!! Что делать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.10.2002, 13:20:57 |
|
||
|
Зачем сканировать таблицу
|
|||
|---|---|---|---|
|
#18+
А сколько всего строк в таблице? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.10.2002, 13:49:35 |
|
||
|
Зачем сканировать таблицу
|
|||
|---|---|---|---|
|
#18+
в таблице ~120 000 строк ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.10.2002, 13:51:31 |
|
||
|
Зачем сканировать таблицу
|
|||
|---|---|---|---|
|
#18+
Попробуй поменять порядок столбцов в индексе, чтобы дата была первой. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.10.2002, 13:57:02 |
|
||
|
Зачем сканировать таблицу
|
|||
|---|---|---|---|
|
#18+
попробовал - аналогичный результат ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.10.2002, 14:02:44 |
|
||
|
Зачем сканировать таблицу
|
|||
|---|---|---|---|
|
#18+
Самый прикол в том, что SELECT count(*) FROM plt WHERE doc_date between '01.01.2002' AND '09.09.2002' таки начинает использовать индекс!!! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.10.2002, 14:16:26 |
|
||
|
Зачем сканировать таблицу
|
|||
|---|---|---|---|
|
#18+
Тогда смотри число операций чтения при использовании и неиспользовании индекса, проверь обновляется ли статистика, если таблица занимает на диске более 8 МБ то она строится по выборочным данным (SAMPLE), построй ее "руками" с опцией FULLSCAN.Посмотри DBCC SHOW_STATISTICS ,думаю где-то здесь "собака порылась" ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.10.2002, 14:18:05 |
|
||
|
Зачем сканировать таблицу
|
|||
|---|---|---|---|
|
#18+
при count(*) все однозначно - индекс "накрывает" запрос ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.10.2002, 14:19:42 |
|
||
|
Зачем сканировать таблицу
|
|||
|---|---|---|---|
|
#18+
1. перестроил статистику с FULLSCAN 2. запустил запрос с выборкой за 4 дня (29 записей) reads = 24 duration=10 3. запустил запрос с выборкой за 5 дней (33 записи) reads = 156 duration=70 4. запустил запрос с выборкой за 5 дней (33 записи) с указанием индекса reads = 41 duration=10 т.е. все то-же самое что же теперь все процедуры переписывать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.10.2002, 15:05:37 |
|
||
|
Зачем сканировать таблицу
|
|||
|---|---|---|---|
|
#18+
Чего тут сказать? Сервер колеблется между проходом по индексу + bookmark lookup и сканированием. Варианты? 1 - добавить annot в индекс, не очень хорошо 2 - сделать этот индекс кластерным, это ИМХО будет получше ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.10.2002, 15:17:12 |
|
||
|
Зачем сканировать таблицу
|
|||
|---|---|---|---|
|
#18+
С каждым разом все интереснее... SELECT inn, annot FROM plt WHERE doc_date between '10.01.2002' AND '11.01.2002' 47 строк - индекс задействован ! reads=73 duration=0 SELECT inn, annot FROM plt WHERE doc_date between '11.01.2002' AND '12.01.2002' 17 строк - индекс не используется !!! reads=156 duration=70 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.10.2002, 15:30:16 |
|
||
|
Зачем сканировать таблицу
|
|||
|---|---|---|---|
|
#18+
А вот еще вариант 2 инlекса - по отдельности по doc_date и по inn ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.10.2002, 15:41:28 |
|
||
|
Зачем сканировать таблицу
|
|||
|---|---|---|---|
|
#18+
попробовал индексы по отдельности - результат тот же а вот когда индекс по doc_date сделал кластерным - совсем другое дело, при выборке за любой период вначале сканируется индекс. На том и порешу. Сделать индекс по дате кластерным - вполне разумно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.10.2002, 15:53:07 |
|
||
|
Зачем сканировать таблицу
|
|||
|---|---|---|---|
|
#18+
А повторяться inn могут? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.10.2002, 16:22:00 |
|
||
|
Зачем сканировать таблицу
|
|||
|---|---|---|---|
|
#18+
на то он и inn, чтобы не повторяться ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.10.2002, 16:25:36 |
|
||
|
Зачем сканировать таблицу
|
|||
|---|---|---|---|
|
#18+
Тогда у меня такая мысль - до того как ты создал кластерный индекс - на таблице был кластырный индекс? Если небыл в принципе или очень давно - то тогда - решаюшим был наверное такой алгоритм - при использованиии обычного индекса на таблице без кластерного индекса - Он пределяет количесто чтений по индексу на какомто участке - и если их больше какого то порогового значения - он начинает сканировать всю таблицу. При кластерном индексе - записи физически перестраивыаются . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.10.2002, 16:41:00 |
|
||
|
Зачем сканировать таблицу
|
|||
|---|---|---|---|
|
#18+
до этого кластерного индекса - не было ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.10.2002, 16:43:53 |
|
||
|
Зачем сканировать таблицу
|
|||
|---|---|---|---|
|
#18+
А нельзя указать точнее, что происходит, когда задействуется индекс? Index scan или Index seek. В случае, если inn-первый столбец индекса, а doc_date-второй. И наоборот. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.10.2002, 13:36:51 |
|
||
|
Зачем сканировать таблицу
|
|||
|---|---|---|---|
|
#18+
SELECT inn, annot FROM plt WHERE doc_date between '10.01.2002' AND '11.01.2002' 47 строк - index seek SELECT inn, annot FROM plt WHERE doc_date between '11.01.2002' AND '12.01.2002' 17 строк - table scan SELECT inn, annot FROM plt (INDEX=my_index) WHERE doc_date between '11.01.2002' AND '12.01.2002' 17 строк - index seek ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.10.2002, 14:20:51 |
|
||
|
|

start [/forum/topic.php?fid=46&msg=32061191&tid=1819349]: |
0ms |
get settings: |
7ms |
get forum list: |
20ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
30ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
73ms |
get tp. blocked users: |
1ms |
| others: | 200ms |
| total: | 352ms |

| 0 / 0 |
