Mysql多列索引使用错误的索引

问题描述 投票:0回答:2

我在产品表上有索引:

  1. products_gender_id_foreign
  2. products_subcategory_id_foreign
  3. idx_products_cat_subcat_gender_used(多列索引)

查询:

select `id`, `name`, `price`, `images`, `used`
from `products`
where `category_id` = '1' and
      `subcategory_id` = '2' and
      `gender_id` = '1' and
      `used` = '0'
order by `created_at` desc
limit 24 offset 0

题:

为什么mysql使用索引

products_subcategory_id_foreign

代替

idx_products_cat_subcat_gender_used(多列索引)

这里解释:

1 SIMPLE产品NULL ref products_gender_id_foreign,products_subcategory_id ... products_subcategory_id_foreign 5 const 2 2.50使用索引条件;用在哪里;使用filesort

mysql sql optimization indexing query-optimization
2个回答
2
投票

正如在MySQL documentation中所解释的那样,在一些环境中可以忽略指数。那些可以适用于你的情况,因为一个索引已经被使用,是:

  • 您正在将索引列与常量值进行比较,并且MySQL已经计算(基于索引树)常量覆盖了表的一部分,并且表扫描会更快。请参见第8.2.1.1节“WHERE子句优化”。
  • 您正在使用具有低基数的键(许多行与键值匹配)通过另一列。在这种情况下,MySQL假设通过使用密钥,它可能会执行许多密钥查找,并且表扫描会更快。

我的猜测是category_id的值不够稀疏


1
投票

正如我所说的here,这个

where `category_id` = '1' and
      `subcategory_id` = '2' and
      `gender_id` = '1' and
      `used` = '0'
order by `created_at` desc
limit 24 offset 0

需要一个5列的综合指数:

INDEX(category_id, subcategory_id, gender_id, used,  -- in any order
      created_at)

到达LIMIT,从而不必获取大量行并对它们进行排序。

关于你选择哪个指数的实际问题......可能一个指数不足的基数比另一个指数要好。

© www.soinside.com 2019 - 2024. All rights reserved.