1

我有这个查询:

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_id, tbl_B. idtbl_Bboolean_value但是mysql仍然说它不使用索引(在不使用索引日志的查询中)并且它检查整个表以检索结果。

我需要知道我应该做些什么来优化这个查询。

编辑:

解释输出:

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
4

2 回答 2

0

如果boolean_value它真的是布尔值索引它不是一个好主意。索引不会有效。

于 2012-07-11T08:41:14.343 回答
0

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

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

  • 也许 5049 行并不是什么大问题,引擎发现使用索引过滤 10% 的行使用索引与不使用它一样快
  • 布尔值仅采用 3 个值:1、0 或 NULL。所以索引的基数总是非常低(最大 3)。查询分析器通常会删除低基数索引(通常认为这个索引对他没有多大帮助是非常正确的)

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

现在通常布尔字段仅对包含多个键的索引有用,因此如果您的查询使用索引的所有字段(在哪里或按顺序),查询分析器将相信该索引是一个真正的好工具。

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

于 2012-07-11T13:49:59.467 回答