做为一名优秀的码农,对于了解Sql如何调优是颇有必要的。。简单总结一下, 1.对查询进行优化,应尽可能避免全表扫描,首先应考虑在 where 及 order by 涉及的列上创建索引(单表索引不能超过六个) 2.使用更多的条件,缩小查找范围 3.使用关联时,用小结果集驱动大结果集 (ps:下面的语句推荐给司机们,赶快上车) --EXPLAIN:表示打出某sql的执行计划,看看是否走了全表,ANALYZE: 表示须要消耗的时间耗时, EXPLAIN ANALYZE SELECT id,a FROM A;
下面是我平常用到的一些Sql优化点,你们能够借鉴一下web
返回了没必要有的数据,就会浪费内存,加剧网络的负担下降性能 。若是表大,在表扫描的期间将表锁住,禁止其余的连接访问表,后果严重!!算法
--correct SQL SELECT * FROM A; --error SQL SELECT id FROM A WHERE create_time >'2019-1-1';
若在关键词abc前面用了“%”,会致使该Sql走全表查询,除非必要,不然不要在关键词前加%
ps: 查询耗时和字段值总长度成正比sql
--error SQL SELECT id FROM A WHERE name LIKE '%abc%'; --correct SQL SELECT id FROM A WHERE name LIKE 'abc%';
该判断将致使引擎放弃使用索引而进行全表扫描,建议针对null字段设置默认值0数据库
--error SQL SELECT id FROM A WHERE a ISNULL; SELECT id FROM A WHERE a NOTNULL; --correct SQL 能够在a上设置默认值0,确保表中a列没有null值 SELECT id FROM A WHERE a =0; SELECT id FROM A WHERE a >0;
该判断将致使引擎放弃使用索引而进行全表扫描,建议将不等于 拆成 大于或者小于缓存
--error SQL SELECT id FROM A WHERE a !=2017; --correct SQL SELECT id FROM A WHERE a >2017 OR a <2017;
使用or的子句能够分解成多个查询,而且经过union连接多个查询。它们的速度只同是否使用索引有关,若是查询使用到联合索引,用unionAll执行的效率更高,多个or字段的字句没有用到索引,改写成union的形式,再视图与索引匹配网络
--error SQL SELECT id FROM A WHERE a >2017 OR a <2017; --correct SQL SELECT id FROM A WHERE a >2017 UNION ALL SELECT id FROM A WHERE a <2017;
NOT IN sql执行时,会转成 <> 将致使引擎放弃使用索引而进行全表扫描,不推荐使用NOT IN
IN 也会使系统没法使用索引,而只能直接搜索表中的数据(ps:若是必定要使用in 注意在in后面值的列表中,将出现最频繁的值放在最前面,出现的最少的放在最后面,减小判断的次数)svg
--error SQL SELECT id FROM A WHERE a IN (2017,2018,2019); SELECT id FROM A WHERE a IN (SELECT id FROM B); --correct SQL 若是查询的是连续的值,可使用BETWEEN AND 函数 SELECT id FROM A WHERE a BETWEEN 2017 AND 2019 --correct SQL 若是只是IN中的子表结果集比较大,建议使用 EXISTS SELECT id FROM A WHERE EXISTS (SELECT 1 FROM B WHERE B.id=a)
IN 是在内存中比较的,只执行一次,把B表中的全部id字段缓存起来,以后检查A表的id是否与B表中的id相等,若是id相等则将A表的记录加入到结果集中,直到遍历完A表的全部记录
EXISTS 须要查询数据库,因此当B的数据量比较大时,EXISTS效率优于IN函数
--error SQL SELECT id FROM A WHERE a IN (SELECT id FROM B); --correct SQL SELECT id FROM A WHERE EXISTS (SELECT 1 FROM B WHERE B.id=a) --correct SQL 若是只是IN子表查询结果,建议使用 EXISTS SELECT id FROM A WHERE EXISTS (SELECT 1 FROM B WHERE B.id=a)
在where子句中的“=”左边进行函数、算数运算或其余表达式运算,系统可能没法正确的使用索引性能
--error SQL SELECT * FROM A WHERE a/2=100; SELECT * FROM A WHERE SUBSTRING(a,1,4)=’6666’; --correct SQL SELECT * FROM A WHERE a=100*2; SELECT * FROM A WHERE a LIKE ’6666%’;
它会使查询变慢,这些动做能够改在客户端执行也能够优化
若是能在group by的having字句以前就能剔除多余的行,因此尽可能不要用他们来作剔除行的动做。最优执行顺序:select 的where字句选择全部合适的行,group用来分组统计,having用于剔除多余的分组。这样group by和having的开销小,查询快。对于大的数据进行分组和having十分消耗资源。若是group by的目的不包括计算,只是分组。Distinct更快
由于inner join是等值链接,或许返回的行数比较少.提倡使用内联INNER JOIN
UNION在进行表连接后会筛选掉重复的记录,UNION ALL不会去除重复记录
UNION将会按照字段的顺序进行排序,UNION ALL只是简单的将两个结果合并后就返回
意思就是使用批处理更有效率
--error SQL INSERT INTO A(id,a) VALUES (1,10); INSERT INTO A(id,a) VALUES (2,16); --correct SQL INSERT INTO A(id,a) VALUES (1,10),(2,16);