2012-05-13 2 views
2

У меня есть очень простой дб схему, которая имеет индекс б-древовидную несколько столбцов на следующие столбцы:PostgreSQL запрос не использует индекс

PersonId, Amount, Commission 

Теперь, если я пытаюсь выбрать таблицу с помощью следующего запроса :

explain select * from "Order" where "PersonId" = 2 AND "Commission" > 3 

Pg сканирует индекс и запрос очень быстро, но если я пытаюсь следующий запрос:

explain select * from "Order" where "PersonId" > 2 AND "Commission" > 3 

это сделать последовательное сканирование, даже если индекс присутствует. Даже этот запрос

explain select * from "Order" where "Commission" > 3 

делает последовательное сканирование. Кто-нибудь может объяснить, почему? :-)

спасибо.

ОБНОВЛЕНИЕ

В таблице содержится 100 миллионов строк. Я создал его только для проверки производительности PostgreSQL против MS SQL. Таблица уже VACUUMED. Я запускаю Core I5 ​​2500k с четырехъядерным процессором и 8 ГБ оперативной памяти.

Вот результат объясняют анализ этого запроса:

explain ANALYZE select * from "Order" where "Commission" BETWEEN 3000000 AND 3000010 LIMIT 20 


Limit (cost=0.00..2218328.00 rows=1 width=24) (actual time=28043.249..28043.249 rows=0 loops=1) 
    -> Seq Scan on "Order" (cost=0.00..2218328.00 rows=1 width=24) (actual time=28043.247..28043.247 rows=0 loops=1) 
     Filter: (("Commission" >= 3000000::numeric) AND ("Commission" <= 3000010::numeric)) 
Total runtime: 28043.278 ms 
+1

смотрите там http://stackoverflow.com/questions/5203755/why-does-postgresql-perform-sequential-scan-on-indexed-column, особенно @Frank Heikens. –

+1

, потому что порядок столбцов индекса имеет значение. прочитайте это: http: // use-the-index-luke.com/sql/where-clause/search-for-range/more-less-between-tuning-sql-access-filter-predicates –

+0

Можете ли вы показать нам операторы 'CREATE TABLE' и' CREATE INDEX' для таблицы? Заявления, которые вы использовали для заполнения таблицы, были бы фантастическими, если бы это было возможно. ('\ d" Order "' output from psql will * do *, но это затрудняет для людей дублирование результатов и тестирование предлагаемых изменений.) Я предполагаю, что данные полностью кэшированы, потому что в противном случае это было бы ужасно сложно чтобы пройти 100 миллионов строк за 28 секунд. Конфигурация по умолчанию предполагает минимальное кэширование, поэтому будет выбран план, основанный на предположении о доступе к диску, который переносится на случайный доступ к индексу. – kgrittn

ответ

6

Короткий ответ в том, что при сравнении различных имеющихся планов, последовательное сканирование, как ожидается, будет самым быстрым, на основе калькуляции факторов вы имеете настроены и доступны последние статистические данные. Из небольшой информации, которую вы предоставили, вполне вероятно, что планировщик сделал правильный выбор. Если у вас есть три индекса с одним столбцом, он может использовать сканирование растровых индексов, особенно если выбранные строки составляют менее 10% строк в таблице.

Обратите внимание, что с индексом, который вы описываете, весь индекс должен быть отсканирован для всех строк, где "PersonId" > 2; который, если у вас много отрицательных значений для "PersonId", скорее всего, будет большой частью таблицы.

Также обратите внимание, что если у вас крошечный стол - скажем несколько тысяч строк или меньше, доступ к строкам через индекс будет редко, чем просто сканирование этих нескольких строк. Планы чувствительны к объему данных, и план, который вы получаете с небольшим количеством строк, вряд ли будет тем же самым планом, который вы получите с большим количеством строк.

Если это, по сути, не самый быстрый план, шансы на то, что вам нужно настроить свои коэффициенты затрат, чтобы лучше моделировать затраты на вашем компьютере. Другая возможность заключается в том, что вам нужно быть более агрессивным в ваших настройках autovacuum, чтобы быть в курсе последних статистических данных, или вам может потребоваться настроить сбор мелкозернистой статистики.

Люди смогут предоставить более конкретные рекомендации, если вы укажете описания таблиц (включая индексы), вывод EXPLAIN ANALYZE для запроса и описание аппаратного обеспечения.

+0

+1 Спасибо за ваш ответ. Я обновил свой пост в соответствии с вашими рекомендациями :) – Davita

Смежные вопросы