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

发布于 2024-11-08 13:25:29 字数 1006 浏览 3 评论 0原文

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

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

它工作得很好..但是如果我尝试选择列“hostname”,或将其添加到选择列列表中,它不会使用实时索引,除非我正在搜索 live=0 .. 这是为什么?

Here is a perplexing issue I am having:

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

Any ideas? This is making me go crazy.. If I just try selecting a single column like this:

EXPLAIN SELECT id FROM queue_servers WHERE live=1

It works just fine.. But if I try to select the column "hostname" , or add it to the select column list, it won't use the live index unless I am searching for live=0 .. Why is this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

晒暮凉 2024-11-15 13:25:29

为什么MySQL不使用索引?
如果很大比例的行具有该值,MySQL 将不会使用索引。

为什么在查询中添加使用索引在这里不起作用
添加 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 将检查整个表。

但我可以使用强制索引
你可以,但是在低基数索引上,它会使你的查询变慢,而不是更快。
仅在复杂查询上覆盖索引,并且如果您知道 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

Why doesn't MySQL not use an index?
MySQL will not use an index if a large percentage of the rows have that value.

Why will adding use index to the query not work here
Adding a use index clause will have no effect, because use index will only suggest which index to use, it will not suggest whether to use an index or not.

Caveat when using test tables with few rows
This is especially vexing when using test tables with few rows as MySQL will refuse to use an index, and it's hard to see what's wrong with your query.
So make sure you add enough rows to a test table to make it a realistic test.

Is using an index on low cardinality columns useless?
Indexing on boolean columns is not as useful as you thought before asking this question.
However it is also not useless either.
With InnoDB MySQL will try and retrieve data using the indexes if possible, if your boolean field has an index the query:

SELECT id, bool_field FROM table_with_many_columns_and_rows WHERE bool_field = 1

Can read all the data in the covering index for bool_field because secondary indexes in InnoDB always include the primary index (id) as well.
This is faster because MySQL does not have to read the entire table into memory.

In MyISAM this doesn't work and MySQL will examine the whole table.

But I can use force index
You can, but on low cardinality indexes it will make your query slower, not faster.
Only override the indexes on complex queries and only if you know the rules MySQL uses to select indexes.

Links:
See: http://dev.mysql.com/doc/refman/5.1/en/mysql-indexes.html
and: http://www.xaprb.com/blog/2006/07/04/how-to-exploit-mysql-index-optimizations/

If you want a book on this subject: read
High performance MySQL: http://oreilly.com/catalog/9780596003067

ぇ气 2024-11-15 13:25:29

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

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

Have you tried enforcing a particular index for search ? http://dev.mysql.com/doc/refman/5.0/en/index-hints.html

You can tell the DBMS to use a proper index for the query. That should give you predictable behaviour.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文