MySQL连接查询不使用索引?

时间:2012-07-11 08:37:49

标签: mysql

我有这个问题:

SELECT 
    COUNT(*) AS `numrows` 
FROM (`tbl_A`) 
JOIN `tbl_B` ON `tbl_A`.`B_id` = `tbl_B`.`id` 
WHERE 
    `tbl_B`.`boolean_value` <> 1;

我为tbl_A添加了三个索引。B_idtbl_Bidtbl_Bboolean_value但是mysql仍然说它没有&# 39;使用索引(在不使用索引日志的查询中)并检查整个表以检索结果。

我需要知道如何优化此查询。

修改

解释输出:

id  select_type table  type  possible_keys          key   key_len  ref      rows  Extra 
1    SIMPLE     tbl_B  ALL   PRIMARY,boolean_value  NULL  NULL     NULL     5049  Using where
1    SIMPLE     tbl_A  ref   B_id                   B_id  9        tbl_B.id 9     Using where; Using index

2 个答案:

答案 0 :(得分:0)

如果boolean_value它真的是布尔值索引它不是那么好主意。指数不会有效。

答案 1 :(得分:0)

该解释向我们展示了一个索引用于连接到tbl_B但是没有索引用于在布尔值上过滤tbl_A。

索引可用,但引擎选择不使用它。为什么会这样:

  • 可能5049行并不是什么大问题,引擎看到使用索引来过滤使用索引这样的行的10%就像在不使用它时一样快。< / LI>
  • 布尔值只有3个值:1,0或NULL。所以索引的基数总是很低(最多3个)。查询分析器通常会丢弃低基数索引(这通常认为这个索引不会帮助他很多)

当您对此布尔值进行50/50的真值和假值重新分区时,或者当您只有几个False时,查看查询分析器的行为是否相同会很有趣。

现在通常布尔字段仅对包含多个键的索引有用,因此,如果查询使用索引的所有字段(在何处或按顺序),查询分析器将信任该索引是一个非常好的工具。 / p>

请注意,索引会降低写入速度并占用额外空间,不会添加无用的索引。使用logt-query-not-using-indexes是一件好事,但你应该使用慢查询日志来补偿这些日志信息。如果查询速度很快,那就不是问题了。