一些简洁实用的做法:
基础内容
1. 建立索引
优化建议: 常用查询字段 建立索引 以及联合索引 (最左优先原则)
2. 避免模糊条件, 例如 null值判断,!=、<>、 or、 in、not in、 %
优化建议:
非常模糊的进行舍弃,
对于 or 可以 分别在索引上查询 并进行union
in, 可以用between
% 可以考虑 全文检索
3. 避免条件中 运算、使用函数
总的来说,尽量可能使用索引。做到 条件明确,直观,简洁,避免全表扫描
注意点:
语句使用:
- in 与 exists 根据两表大小使用,子查询表大用exists , 子查询表小用 in
- select * from A where exists (select * from B where B.id = A.id);
- select * from A where A.id in (select id from B);
- 尽量避免使用临时表
- 大的结果集尽量不用游标,效率差,占用连接
- 避免一次性返回大量数据,建议分批返回
创建方面:
- 字段设置,纯数字尽量不要设置为字符类型,字符类型的在查询和连接时,会逐个比较每个字符,数字仅需一次
- 字符尽量使用变长类型的,varchar nvarchar ,一个减小空间,二是较小字段搜索效率高 ### 有待查询
结果方面:
- 尽量使用具体的列名, 不要使用 select *
做到,从前往后,先把范围缩小,然后再查,降低子查询的命中率。
链接:
http://blog.jobbole.com/86594/
一些分析:
通常 从命中率,区分度来简单分析,这里是先分析一下一个问题:
有一个 shop_setting 的表,表内数据量并不大,但是却出现在了慢查询日志中,所以就找找问题原因。
首先是 查看查询的语句,很简单,就是单表查询,少数的列,条件也是对某些列进行的and 操作。
然后最普遍的是,查看索引,查看后发现,在条件中的一些字段都分别建立了索引,然后根据下面这篇文章链接得知,MySQL5.0后的索引合并策略 或分别在 各个建立单子段索引的列上进行索引查询,然后进行交集或是并集的操作以达到提高效率。但是,通常情况下,这种在某些数据上面会有些许问题。
在本次问题中,各列均是建立的单列索引查询的时候会使用索引,但是为什么还是会出现在慢查询日志中呢。
此时就要考虑一下 数据的情况了,通常可以看一下 数据的区分度,可以这样 select count(*) from table1; 查看总数。然后使用select count(*) from table1 group by col1 ; 查看结果的数量,比较一下就能轻松判断出区分度。所以就查了一下,惊人的发现,其中总共有 三个列 作为条件,有两个列大多数的值就是相同的(也就是区分度很低),所以就导致了即使使用索引合并,使用索引查询,命中数仍然很高,索引合并的时候就会耗费更多的时间。
那么应该怎么做呢,通常这样的应该是 根据使用情况 使用多列索引 尽可能做到索引覆盖到大多数的查询。把区分度较高的列放在前面,对于一些区分度较低的列 在没有必要的情况下可以不做索引,以提高插入和更新的效率。