MySQL 索引综合示例

创建索引:

create index idx_test_c1234 on test(c1,c2,c3,c4);

测试索引:

-- 全值匹配可以使用索引
EXPLAIN SELECT * FROM test WHERE `c1`='a1' AND `c2`='a2' AND `c3`='a3' AND `c4`='a4';
-- 查询优化器优化后可以使用索引
EXPLAIN SELECT * FROM test WHERE `c1`='a1' AND `c2`='a2' AND `c4`='a4' AND `c3`='a3';
-- 查询优化器优化后可以使用索引
EXPLAIN SELECT * FROM test WHERE `c4`='a4' AND `c3`='a3' AND `c2`='a2' AND `c1`='a1';

-- 只能用到前三个索引,第四个失效
EXPLAIN SELECT * FROM test WHERE `c1`='a1' AND `c2`='a2' AND `c3`>'a3' AND `c4`='a4';

-- 可以用到四个索引,第四个用于排序,查询优化器会优化为:AND `c3`='a3' AND `c4`>'a4';
EXPLAIN SELECT * FROM test WHERE `c1`='a1' AND `c2`='a2' AND `c4`>'a4' AND `c3`='a3';

-- 查找用到了两个索引,排序用到了一个索引,无 filesort
EXPLAIN SELECT * FROM test WHERE `c1`='a1' AND `c2`='a2' AND `c4`='a4' ORDER BY c3;

-- 查找用到了两个索引,排序用到了一个索引,无 filesort
EXPLAIN SELECT * FROM test WHERE `c1`='a1' AND `c2`='a2' ORDER BY c3;

-- 查找用到了两个索引,排序没有用到索引,而是使用了文件排序
EXPLAIN SELECT * FROM test WHERE `c1`='a1' AND `c2`='a2' ORDER BY c4;

-- 查找用到了一个索引,排序用到了两个索引,无 filesort
EXPLAIN SELECT * FROM test WHERE `c1`='a1' AND `c5`='a5' ORDER BY c2, c3;

-- 查找用到了一个索引,排序无法使用索引
EXPLAIN SELECT * FROM test WHERE `c1`='a1' AND `c5`='a5' ORDER BY c3, c2;

-- 查找用到了两个索引,排序用到了两个索引,无 filesort
EXPLAIN SELECT * FROM test WHERE `c1`='a1' AND `c2`='a2' ORDER BY c2, c3;
EXPLAIN SELECT * FROM test WHERE `c1`='a1' AND `c2`='a2' AND `c5`='a5' ORDER BY c2, c3;

-- 查找用到了两个索引,排序使用了一个索引(查询条件中c2是常量,只有唯一值,不需要再进行排序),无 filesort
EXPLAIN SELECT * FROM test WHERE `c1`='a1' AND `c2`='a2' AND `c5`='a5' ORDER BY c3, c2;

-- 查找用到了一个索引,分组可以使用索引
EXPLAIN SELECT * FROM test WHERE `c1`='a1' AND `c4`='a4' GROUP BY c2, c3;

-- 查找用到了一个索引,分组没有使用索引(使用了临时表和文件排序)
-- 分组的前提是排序,分组的索引原则基本上与排序一致
EXPLAIN SELECT * FROM test WHERE `c1`='a1' AND `c4`='a4' GROUP BY c3, c2;
-- 查找用到了三个索引,模糊查询后的字段可以继续使用索引(与大于小于不同)
EXPLAIN SELECT * FROM test WHERE `c1`='a1' AND `c2` like 'kk%' AND c3='a3';

-- 查找用到了一个索引,模糊查询不能使用索引
EXPLAIN SELECT * FROM test WHERE `c1`='a1' AND `c2` like '%kk' AND c3='a3';
EXPLAIN SELECT * FROM test WHERE `c1`='a1' AND `c2` like '%kk%' AND c3='a3';

-- 查找用到了三个索引,模糊查询后的字段可以继续使用索引(与大于小于不同)
EXPLAIN SELECT * FROM test WHERE `c1`='a1' AND `c2` like 'k%kk%' AND c3='a3';

索引的优化建议:

  • 单列索引尽量选择过滤性更好的字段。
  • 组合索引尽量把过滤性最好的字段放在左边。
  • 组合索引尽量选择能够包含查询语句中更常用的字段。
  • 尽可能通过分析统计信息和调整查询语句写法来达到选择合适索引的目的。

你可能感兴趣的:(mysql)