首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Mysql索引被忽略

问Mysql索引被忽略
EN

Stack Overflow用户
提问于 2009-06-03 17:11:55
回答 3查看 4.6K关注 0票数 4
代码语言:javascript
复制
EXPLAIN SELECT
*
FROM
content_link link
STRAIGHT_JOIN
content
ON
link.content_id = content.id
WHERE
link.content_id = 1
LIMIT 10;

+----+-------------+---------+-------+---------------+------------+---------+-------+------+-------+
| id | select_type | table   | type  | possible_keys | key        | key_len | ref   | rows | Extra |
+----+-------------+---------+-------+---------------+------------+---------+-------+------+-------+
|  1 | SIMPLE      | link    | ref   | content_id    | content_id | 4       | const |    1 |       |
|  1 | SIMPLE      | content | const | PRIMARY       | PRIMARY    | 4       | const |    1 |       |
+----+-------------+---------+-------+---------------+------------+---------+-------+------+-------+

但是,当我删除WHERE时,查询将停止使用键(即使我显式强制它)

代码语言:javascript
复制
EXPLAIN SELECT
*
FROM
content_link link FORCE KEY (content_id)
STRAIGHT_JOIN
content
ON
link.content_id = content.id
LIMIT 10;

+----+-------------+---------+--------+---------------+---------+---------+------------------------+---------+-------------+
| id | select_type | table   | type   | possible_keys | key     | key_len | ref                    | rows    | Extra       |
+----+-------------+---------+--------+---------------+---------+---------+------------------------+---------+-------------+
|  1 | SIMPLE      | link    | index  | content_id    | PRIMARY | 7       | NULL                   | 4555299 | Using index |
|  1 | SIMPLE      | content | eq_ref | PRIMARY       | PRIMARY | 4       | ft_dir.link.content_id |       1 |             |
+----+-------------+---------+--------+---------------+---------+---------+------------------------+---------+-------------+

有没有解决这个问题的办法?

我意识到我在第二个示例中选择了整个表,但是为什么mysql突然决定无论如何都要忽略我的力并且不使用键呢?如果没有键,查询大约需要10分钟。呃。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-06-03 17:21:08

力量是一个有点用词不当的词。以下是MySQL文档所说的(重点是我的):

您还可以使用FORCE INDEX,它的作用类似于use INDEX (index_list),但是假定表扫描的开销非常大。换句话说,只有当无法使用给定的索引之一来查找表中的行时,才使用a表扫描。

因为您实际上没有“找到”任何行(您选择了所有行),所以表扫描总是最快的,并且优化器足够聪明,无论您告诉他们什么,都知道这一点。

预计到达时间:

尝试在主键上添加ORDER BY一次,我打赌它会使用索引。

票数 4
EN

Stack Overflow用户

发布于 2009-06-03 17:13:50

索引有助于在表中快速搜索,但如果选择整个表,它只会减慢搜索速度。因此,MySQL忽略索引是正确的。

在您的例子中,索引可能有一个MySQL不知道的隐藏副作用。例如,如果内连接只适用于几行,则索引将加快速度。但是如果没有明确的提示,MySQL是不会知道的。

有一个例外:当您选择的每一列都在索引内时,如果您选择每一行,则索引仍然有用。例如,如果您在LastName上有一个索引,则以下查询仍可从该索引中受益:

代码语言:javascript
复制
select LastName from orders

但这一条不会:

代码语言:javascript
复制
select * from Orders
票数 4
EN

Stack Overflow用户

发布于 2009-06-03 17:31:43

您的content_id似乎接受NULL值。

MySQL优化器认为不能保证您的查询只通过使用索引就能返回所有值(尽管实际上有保证,因为您在JOIN中使用了列)

这就是它恢复为全表扫描的原因。

添加NOT NULL条件:

代码语言:javascript
复制
SELECT  *
FROM    content_link link FORCE KEY (content_id)
STRAIGHT_JOIN
        content
ON      content.id = link.content_id
WHERE   link.content_id IS NOT NULL
LIMIT 10;

或者将您的列标记为NOT NULL

代码语言:javascript
复制
ALTER TABLE content_link MODIFY content_id NOT NULL

更新:

这是在MySQL中验证的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/945925

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档