数据库表添加索引可以提高查询效率,开发中我们经常使用的索引有唯一索引和组合索引。
唯一索引 (数据库表多列加上唯一索引,可以保证在并发条件下,数据库不会有脏数据。因为
在开发中,我们很多业务场景都需要保证数据库记录的唯一。如果字段建立了唯一索引,但是
值为null,这时唯一索引是不生效的,这时可以考虑用空字符串代替null)
组合索引 (给数据库表的多列建立索引,该索引不保证唯一性,目的是提高数据库查询的效率)
索引底层的数据结构是 B+ 树,它可以减小硬盘与内存之间的 IO,以提高检索效率。建立索引的原则:
<最左匹配原则> 对于多列索引, mysql 总是从最左匹配,中间的不可以跳过。例如建立了索引
idx_name_age_gender. 查询时会优先匹配 name 字段,然后 age 字段,最后匹配 gender 字段。
中间的字段不可以跳过。mysql 会一直向右匹配,直至遇到(>, <, between, like 字段就停止);
因此,我们在创建组合索引时,把 where 子句使用最频繁的放在最前面。
<=和in可以乱序> ,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式
<选择区分度高的字段建立索引> 区分度 count(distinct col)/count(*),表示字段不重复的比例,比例越大我们扫描的记录数越少;
<索引值不要参加运算>。如果索引值参与运算,每次索引前都要计算一次,成本太高;
尽量不要新建索引,可以在原索引的基础上进行扩展;
SQL 优化
like 后面的参数如果以 通配符开头,不会走索引查询,会走全表扫描;
where 子句不符合 最左匹配原则时,不会走索引查询;例如 device_info 表 索引 idx_devicename_devicecategory,
select * from device_info where device_name = "xxx" , 这个sql 就不会走索引查询;
避免在where子句中使用or来连接条件,否则将导致引擎放弃使用索引而进行全表扫描 .这时可以考虑使用 union 代替;
尽量避免使用!=, <, > 操作符,否则数据库引擎会放弃使用索引而进行全表扫描;
避免使用 select * . 在解析的过程中,会将’*’ 依次转换成所有的列名,这是通过查询数据字典完成的,会耗费更多的时间;
可以使用 destinct 就不要使用 groupBy;
如果应用程序有很多 join 查询,最好给两个表中Join的字段建立索引;
如果sql 执行比较慢,可以考虑使用explain 语句查看sql 的执行计划;