MySQL在检查= 1时不使用索引,但在= 0时使用它

bom*_*omp 4 mysql indexing innodb

这是我遇到的一个令人困惑的问题:

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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?这让我变得疯狂..如果我只是尝试选择这样一个列:

EXPLAIN SELECT id FROM queue_servers WHERE live=1
Run Code Online (Sandbox Code Playgroud)

它工作正常..但如果我尝试选择列"hostname",或将其添加到选择列列表,它将不会使用实时索引,除非我搜索live = 0 ..为什么这样?

Joh*_*ica 16

为什么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
Run Code Online (Sandbox Code Playgroud)

可以读取覆盖索引中的所有数据,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的折射率的优化/

如果你想要一本关于这个主题的书:阅读
高性能MySQL:http://oreilly.com/catalog/9780596003067


Par*_*rth -2

您是否尝试过强制执行特定的搜索索引?http://dev.mysql.com/doc/refman/5.0/en/index-hints.html

您可以告诉 DBMS 使用正确的索引进行查询。这应该会给你可预测的行为。