MySQL -- 查询优化 一

索引建立技巧

单个字段 “等于” 查询

形如:

1
SELECT * FROM `tabel1` WHERE `f1` = 15

这种情况下,毫无疑问,需要给字段 (f1) 加上索引。

形如:

1
SELECT `f2`,`f3` FROM `tabel1` WHERE `f1` = 15

此时应该创建 (f1,f2,f3) 索引,此索引起到覆盖索引的作用,效率比 (f1) 索引高。切记,不应该创建 (f2,f3,f1) 索引,因为根据索引 “最左原则”,它对 f1 字段起不到查询过滤作用。

多个字段 “等于” 查询

形如:

1
SELECT * FROM `tabel1` WHERE `f1` = 15 AND `f2` = "abc"

这种情况下,应该创建 (f1,f2)索引 或者 (f2,f1)索引 都是可以的。
有人会问,如果创建两个单独是索引,分别是 (f1)索引 和 (f2)索引 可以吗?这里不建议这么做,虽然MySQL根据index_merge算法能同时使用这两个索引,但这样效率依旧不如上面联合索引。

字段 “等于” 和 “不等于” 混合查询

形如:

1
SELECT * FROM `tabel1` WHERE `f1` > 15 AND `f2` = "abc"

对于这种情况,我们要小心处理,因为只要有一列使用了不等于计算,那么它将阻止其他列使用索引。
此时我们应该创建 (f2,f1) 索引,这时候f1和f2两个条件都会走索引,这才是我们想要的。而不是 (f1,f2) 索引,这种情况下,只有 f1 会使用索引,相对来说效率较低。

形如:

1
SELECT * FROM `tabel1` WHERE `f1` > 15 AND `f3` < 100 AND `f2` = "abc"

这是有两个 “不等于” 查询,因此我们不可能做到 f1,f2,f3都做到被索引覆盖,
此时需要依据实际数据情况,建立 (f2,f1)索引 或 (f2,f3)索引,其中关键是,一定要把 “等于” 字段,放在索引的最左侧。

多个字段 “等于” 和 “排序” 查询

形如:

1
SELECT * FROM `tabel1` WHERE `f1` = 15 AND `f2` = "abc" ORDER BY `f3`

此时我们建立索引的字段顺序,应该是: “先是过滤字段,后是排序字段”,所以此处应该建立 (f1,f2,f3)索引 或者 (f2,f1,f3)索引。而不应该 建立 (f3,f1,f2)索引 或者 (f3,f2,f1)索引,因为这些只使用了索引排序,没有使用索引过滤。

形如:

1
SELECT `f4`,`f5` FROM `tabel1` WHERE `f1` = 15 AND `f2` = "abc" ORDER BY `f3`

此时我们可以创建 (f1,f2,f3,f4,f5)索引 或 (f2,f1,f3,f4,f5)索引,起到了 过滤,排序和覆盖 三个作用。

字段 “不等于” 和 “排序” 查询

形如:

1
SELECT * FROM `tabel1` WHERE `f1` > 15 AND `f2` = "abc" ORDER BY `f3`

此时,需要根据实际数据情况,选择建立 (f2,f1)索引 或 (f2,f3)索引

形如:

1
SELECT * FROM `tabel1` WHERE `f1` > 15 ORDER BY `f3`

此时,只可能一个字段使用到索引,要么使用 (f1)索引,要么使用 (f2)索引,这要依据集体的数据情况,一般情况下会使用过滤索引,也就是 (f1)索引。