sql语句优化
SQL语句没写好可能导致:
1)网速不给力,不稳定。
2)服务器内存不够,或者SQL 被分配的内存不够。
3)sql语句设计不合理
4)没有相应的索引,索引不合理
5)没有有效的索引视图
6)表数据过大没有有效的分区设计
7)数据库设计太2,存在大量的数据冗余
8)索引列上缺少相应的统计信息,或者统计信息过期
那么怎么对SQL进行优化呢?
1.不查询多余的行与列
尽量不要使用 select * 去查询,应该使用具体的那一列代替 * ,避免多余不需要使用的列。
使用where条件判断具体要查询的数据避免查询出多余的列。
使用distinct关键词避免重复的列。
2.谨慎使用distinct关键字
distinct在查询一个字段或者很少字段的情况下使用,会避免重复数据的出现,给查询带来优化效果。
但是查询字段很多的情况下使用,则会大大降低查询效率。
3.连接查询的优化
首先你要弄明白你想要的数据是什么样子的,然后再做出决定使用哪一种连接,这很重要。
各种连接的取值大小为:
内连接结果集大小取决于左右表满足条件的数量
左连接取决与左表大小,右相反。
完全连接和交叉连接取决与左右两个表的数据总数量
4.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:
select id from t where num is null --可以在num这个列上给个默认约束等于0 然后 num = 0
5.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:
select id from t where num=10 or num=20 --这种不就是相当于是个in吗? in不就是不走引索的吗 #可以这样查询: select id from t where num=10 union all select id from t where num=20
6.模糊搜索
select id from t where name like '%abc%' --也将导致全表扫描
'%abc' 这种也将导致全表扫描,尽量使用 'abc%' ---后通配 走索引 前通配 走全表。
若要提高效率,可以考虑全文检索。
7.in 和 not in 也要慎用,否则会导致全表扫描,如:
select id from t where num in(1,2,3) -- 对于连续的数值,能用 between 就不要用 in 了: select id from t where num between 1 and 3
8.很多时候用 exists 代替 in 是一个好的选择:
select num from a where num in(select num from b) 用下面的语句替换: select num from a where exists(select 1 from b where num=a.num)
9.索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。
10.不使用子查询
SELECT * FROM t1 WHERE id in(SELECT id FROM t2 WHERE name='SimpleWu');--避免使用
子查询在MySQL5.5版本里,内部执行计划器是这样执行的:先查外表再匹配内表,而不是先查内表t2,当外表的数据很大时,查询速度会非常慢。
在MariaDB10/MySQL5.6版本里,采用join关联方式对其进行了优化,这条SQL会自动转换为
SELECT t1.* FROM t1 JOIN t2 ON t1.id = t2.id where t2.name="SimpleWu";
11. !=或者<>(不等于),可能导致不走索引,也可能走 INDEX FAST FULL SCAN
不知道SQL语句是否走引索?可以这样
EXPLAIN SELECT * FROM cnblogs_blog WHERE bno = 1