MySQL索引优化-使用两个不同索引的同一查询必须查看1100万行-为什么会这样?

qvsjd97n  于 2023-04-05  发布在  Mysql
关注(0)|答案(1)|浏览(102)

假设在这个明显人为的示例中有三个表PartsBrandWarehouse
Parts具有id、brand_id和warehouse_id index_parts_on_brand_id index_parts_on_brand_id_and_warehouse_id
我们跑

SELECT COUNT(*) FROM `parts` WHERE `parts`.`brand_id` = {some_id};

当我对一个拥有大量部件(在本例中为700万)的品牌运行此查询并检查查询计划时,我可以看到mysql使用index_parts_on_brand_id_and_warehouse_id索引。
如果我强制mysql使用index_parts_on_brand_id,如下所示:

SELECT COUNT(*) FROM `parts` FORCE INDEX (index_parts_on_brand_id) WHERE `parts`.`brand_id` = {some_id};

使用每个索引时:index_parts_on_brand_id

  • 类型:参考
  • extra:使用索引
  • 必须查看13,012,370行13,012,370

index_parts_on_brand_id_and_warehouse_id

  • 类型:参考
  • extra:使用索引
  • 必须查看2,391,314

我很惊讶地看到,数据库在使用index_parts_on_brand_id时不得不多看近1100万条记录。
为什么mysql必须查看这么多额外的行?我希望mysql在使用index_parts_on_brand_idindex_parts_on_brand_id_and_warehouse_id时必须查看相同或更少的行
谢谢大家!

tzdcorbm

tzdcorbm1#

“必须查看13,012,370行”--这是一个谬论。
EXPLAIN * 估计 * 它呈现给你的数字。有时它们相差很远。不要相信它们。
另一方面,do trustextra: Using index。这意味着INDEX是“覆盖”的,这意味着它使用了索引的BTree而不是数据的BTree。这很好。
但是,…它仍然需要查看数百万行。
要获取“触摸”的确切行数,可以使用EXPLAIN ANALYZE(如果可用)或使用Handler值:http://mysql.rjweb.org/doc.php/index_cookbook_mysql#handler_counts
我真的需要看到SHOW CREATE TABLE和查询的完整示例。这里有一个常见的错误,可以防止使用索引:

CREATE TABLE ... brand_id VARCHAR(...) ...

WHERE brand_id = 123

陷阱是将字符串列与数字文字进行比较。

相关问题