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时,查询将停止使用键(即使我显式强制它)
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分钟。呃。
发布于 2009-06-03 17:21:08
力量是一个有点用词不当的词。以下是MySQL文档所说的(重点是我的):
您还可以使用FORCE INDEX,它的作用类似于use INDEX (index_list),但是假定表扫描的开销非常大。换句话说,只有当无法使用给定的索引之一来查找表中的行时,才使用a表扫描。
因为您实际上没有“找到”任何行(您选择了所有行),所以表扫描总是最快的,并且优化器足够聪明,无论您告诉他们什么,都知道这一点。
预计到达时间:
尝试在主键上添加ORDER BY一次,我打赌它会使用索引。
发布于 2009-06-03 17:13:50
索引有助于在表中快速搜索,但如果选择整个表,它只会减慢搜索速度。因此,MySQL忽略索引是正确的。
在您的例子中,索引可能有一个MySQL不知道的隐藏副作用。例如,如果内连接只适用于几行,则索引将加快速度。但是如果没有明确的提示,MySQL是不会知道的。
有一个例外:当您选择的每一列都在索引内时,如果您选择每一行,则索引仍然有用。例如,如果您在LastName上有一个索引,则以下查询仍可从该索引中受益:
select LastName from orders但这一条不会:
select * from Orders发布于 2009-06-03 17:31:43
您的content_id似乎接受NULL值。
MySQL优化器认为不能保证您的查询只通过使用索引就能返回所有值(尽管实际上有保证,因为您在JOIN中使用了列)
这就是它恢复为全表扫描的原因。
添加NOT NULL条件:
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
ALTER TABLE content_link MODIFY content_id NOT NULL更新:
这是在MySQL中验证的。
https://stackoverflow.com/questions/945925
复制相似问题