Индекс MySQL отсутствует - PullRequest
3 голосов
/ 05 мая 2011

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

select count(*) from `foo` where expires_at < now()”

поскольку expires_at проиндексирован, запрос попадает в индекс без проблем. однако следующий запрос:

select count(*) from `foo` where expires_at < now() and some_id != 5

индекс никогда не попадет.

и expires_at, и some_id проиндексированы.

мой индекс создан неправильно?

Ответы [ 3 ]

1 голос
/ 05 мая 2011

Этот запрос:

SELECT  COUNT(*)
FROM    foo
WHERE   expires_at < NOW()

может быть удовлетворен только индексом, без ссылки на саму таблицу.Вы можете увидеть это из using index в плане.

Этот запрос:

SELECT  COUNT(*)
FROM    foo
WHERE   expires_at < NOW()
        AND some_id <> 5

необходимо просмотреть таблицу, чтобы найти значение some_id.

Поскольку поиск в таблице является довольно дорогой вещью, более эффективно использовать сканирование таблицы и фильтровать записи.

Если у вас составной индекс в expires_at, some_id, запрос, вероятно, будет использовать индекскак для ранжирования по expires_at, так и для фильтрации по some_id.

SQL Server даже предлагает функцию, известную как included fields для этого.Эта команда

CREATE INDEX ix_foo_expires__someid ON foo (expires_at) INCLUDE (some_id)

создаст индекс для expires_at, который дополнительно сохранит some_id в конечных точках (без затрат на сортировку).

MySQL, к сожалению, делаетне поддерживает его.

0 голосов
/ 05 мая 2011

1) Кажется, у вас есть два столбца индекса.Вы можете попытаться создать многостолбцовый индекс.

Подробное объяснение того, почему он отличается от нескольких одностолбцовых индексов, см. В следующем документе: http://www.mysqlfaqs.net/mysql-faqs/Indexes/When-does-multi-column-index-come-into-use-in-MySQL

2) У вас естьИндекс B-дерева в столбце expires_at?Поскольку вы выполняете запрос диапазона (<), это может повысить производительность. </p>

http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html

Удачи!

0 голосов
/ 05 мая 2011

Вероятно, происходит то, что для первого запроса индекс может использоваться для подсчета строк, удовлетворяющих предложению WHERE. Другими словами, запрос приведет к сканированию таблицы, но, к счастью, все столбцы, включенные в условие WHERE, будут в индексе, поэтому индекс сканируется вместо этого.

Во втором запросе нет единого индекса, который содержал бы все столбцы в предложении WHERE. Таким образом, MySQL прибегает к полному сканированию таблицы. В случае первого запроса он использовал ваш индекс, но не для поиска строк для проверки - в особом случае запроса COUNT() он мог бы использовать индекс для подсчета строк. Это было эквивалентно сканированию таблицы, но по индексу, а не по таблице.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...