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

时间:2018-08-17 22:19:51

标签: mysql sql optimization indexing query-optimization

我在产品表上有索引:

  1. PRIMARY
  2. products_gender_id_foreign
  3. products_subcategory_id_foreign
  4. 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个简单产品NULL ref products_gender_id_foreign,products_subcategory_id ... products_subcategory_id_foreign 5 const 2 2.50使用索引条件;在哪里使用使用文件排序

2 个答案:

答案 0 :(得分:2)

MySQL documentation中所述,在某些情况下可以忽略索引。由于已经使用了一个索引,因此可能适用于您的情况的是:

  • 您正在将索引列与常量值进行比较,而MySQL具有 计算(基于索引树)常量也覆盖 很大一部分表格,表格扫描会更快。看到 第8.2.1.1节“ WHERE子句优化”。

  • 您正在使用基数较低的键(许多行与该键匹配) 值)通过另一列。在这种情况下,MySQL假定 使用键,它可能会执行许多键查找,并且一个表 扫描会更快。

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

答案 1 :(得分: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,从而不必获取很多行并对它们进行排序。

关于您实际选择哪个索引的问题……一个索引不足的基数可能比另一个索引的基数好。