-
- 避免在索引列上使用表达式或隐式类型转换。
- 尽量避免在where条件中使用NOT、<>、!= 等操作符,因为这些可能会导致引擎放弃使用索引而使用全表扫描。
- or的两个条件都有索引的话,用union或union all代替or。
- 条件列没有索引情况下,用in操作符替换or,在mysql中or的效率为O(n),而in的效率为O(log2n)。
- 若条件范围内是连续的数值,建议使用between操作符替换in。
- 子查询结果集较大时,适合用EXISTS(EXIST先查询主表,再查询从表)子查询结果集较小时,适合用IN(IN先查询从表,再查询主表)。
- 不建议使用%前缀模糊查询(例如%a% 、 %a), 因为会导致引擎放弃使用索引而进行全表扫描; 如果需要用%a%模糊查询,可采用全文索引方式解决。
ALTER TABLE `dynamic_201606` ADD FULLTEXT INDEX `idx_user_name` (`user_name`)。
- 若索引列已经设置了不能为NULL,则使用IsNull、Is Not NULL毫无意义,会导致索引失效,走全表扫描。
- 若结果集没有重复数据或者允许出现重复数据,则使用UNION ALL替换UNION,union和union all的差异主要是前者需要将结果集合并后再进行唯一性过滤操作,这就会涉及到排序,增加大量的CPU运算,加大资源消耗及延迟。
- Sql语句不应该过于冗长,合理利用临时表。
- 对于联合索引来说,要遵守最左前缀法则,举列来说索引含有字段id,name,school,可以直接用id字段,也可以id,name这样的顺序,但是name,school都无法使用这个索引。所以在创建联合索引的时候一定要注意索引字段顺序,常用的查询字段放在最前面。
- 尽量使用inner join,避免left join,如果连接方式是inner join,在没有其他过滤条件的情况下MySQL会自动选择小表作为驱动表,但是left join在驱动表的选择上遵循的是左边驱动右边的原则,即left join左边的表名为驱动表。
- 语句中避免使用*符号,用具体字段代替*。原因:浪费流量;全表扫描,读硬盘,IO次数增多,索引失效。
- 批量插入时,建议一次性插入,而不是一条条插入,但批量操作需要把握一个度,建议每批数据尽量控制在500以内。如果数据多于500,则分多批次处理。
- 使用Join操作多个表时,应确保操作表的数量不宜过多,最多不超过3个表。如果join太多,MySQL在选择索引的时候会非常复杂,很容易选错索引。
- In中的值不宜过多。最好不要超过500个,若大于500,建议分批查询然后汇总。
- 选择合适的字段类型,例如
- 能用数字类型,就不用字符串,因为字符的处理往往比数字要慢。
- 尽可能使用小的类型,比如:用bit存布尔值,用tinyint存枚举值等。
- 长度固定的字符串字段,用char类型。
- 长度可变的字符串字段,用varchar类型。
- 金额字段用decimal,避免精度丢失问题。
- 控制索引数量,索引数量最好不要超过5个。
- 表数据量较大时,使用连接查询代替子查询。因为执行子查询时,需要创建临时表,查询完毕后,需要再删除这些临时表,有一些额外的性能消耗。