MySQL не использует индекс при проверке = 1, но использует его с = 0 - PullRequest
4 голосов
/ 22 мая 2011

Вот проблема, которая у меня возникла:

Query:
EXPLAIN SELECT id,hostname FROM queue_servers WHERE live=1

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra

1   SIMPLE  queue_servers   ALL     live    NULL    NULL    NULL    6   Using where

Query:
EXPLAIN SELECT id,hostname FROM queue_servers WHERE live=0

id  select_type     table   type    possible_keys   key     key_len     ref     rows    Extra

1   SIMPLE  queue_servers   ref     live    live    1   const   1

SHOW INDEXES FROM queue_servers

Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type

queue_servers   1   live    1   live    A   6   NULL    NULL        BTREE

Есть идеи? Это сводит меня с ума. Если я просто попытаюсь выбрать один столбец, как это:

EXPLAIN SELECT id FROM queue_servers WHERE live=1

Работает просто отлично. Но если я попытаюсь выбрать столбец "имя хоста" или добавить его в список выбора столбцов, он не будет использовать живой индекс, если я не ищу live = 0 .. Почему это?

Ответы [ 2 ]

16 голосов
/ 22 мая 2011

Почему MySQL не использует индекс?
MySQL не будет использовать индекс, если это значение имеет большой процент строк.

Почему добавление use index к запросу здесь не работает
Добавление предложения use index не будет иметь никакого эффекта, поскольку use index будет только предлагать какой индекс использовать, но не будет предлагать, использовать индекс или нет.

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

Бесполезно ли использование индекса для столбцов с низким числом элементов?
Индексирование по логическим столбцам не так полезно , как вы думали, прежде чем задавать этот вопрос.
Однако это также не бесполезно либо.
С InnoDB MySQL будет пытаться получать данные, используя индексы, если это возможно, если ваше логическое поле имеет индекс запроса:

SELECT id, bool_field FROM table_with_many_columns_and_rows WHERE bool_field = 1

Может считывать все данные в покрывающем индексе для bool_field, потому что вторичные индексы в InnoDB всегда включают первичный индекс (id) .
Это быстрее, потому что MySQL не должен читать всю таблицу в память.

В MyISAM это не работает, и MySQL проверит всю таблицу.

Но я могу использовать force index
Вы можете, но при низких показателях кардинальности ваш запрос будет выполняться медленнее, а не быстрее. Переопределять индексы только для сложных запросов и только , только если вы знаете правила, используемые MySQL для выбора индексов.

Ссылки:
См .: http://dev.mysql.com/doc/refman/5.1/en/mysql-indexes.html
и: http://www.xaprb.com/blog/2006/07/04/how-to-exploit-mysql-index-optimizations/

Если вам нужна книга на эту тему: прочитайте
Высокая производительность MySQL: http://oreilly.com/catalog/9780596003067

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

Вы пытались применить определенный индекс для поиска? http://dev.mysql.com/doc/refman/5.0/en/index-hints.html

Вы можете указать СУБД использовать правильный индекс для запроса. Это должно дать вам предсказуемое поведение.

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