SQL常见调优


  • 查询SQL尽量不要使用* 而是select 具体字段
  • 统计行数时,count(1)优于count(*)
  • 尽量避免在where子句中使用or来进行条件连接.or会使索引失效,导致全表扫描 查询id为1 或者deptno为30的员工 要么分两句 要么用UNION.
select * from emp where empno = 1 or deptno=30
  • like语句优化 %号不可以放在第一位
select * from emp where empno like '%123';--不会使用索引,会直接全表扫描
select * from emp where empno like '123%';-- 索引还是可以正常使用的
  • 使用where 条件限定查询的数据,避免返回多余的行.
  • 尽量避免在建立索引的字段上使用函数.
  • Inner join 、left join、right join,优先使用 Inner join,如果是 left join, 左边表结果尽量小Inner join 内连接,在两张表进行连接查询时,只保留两张表中完全匹配的结果集。left join 在两张表进行连接查询时,会返回左表所有的行,即使在右表中没有匹配的记录。right join 在两张表进行连接查询时,会返回右表所有的行,即使在左表中没有匹配的记录。 都满足 SQL 需求的前提下,推荐优先使用 Inner join(内连接),如果要使用 left join,左边表数据结果尽量小,如果有条件的尽量放到左边处理。
select * from tab1 t1 left join tab2 t2  on t1.size = t2.size where t1.id>2;
select * from (select * from tab1 where id >2) t1 left join tab2 t2 on t1.size = t2.size;

  • 应尽量避免在 where 子句中使用!=或<>操作符,
  • 否则将引擎放弃使用索引而进行全表扫描
反例:
select age,name  from user where age <>18;
正例:
//可以考虑分开两条sql写
select age,name  from user where age <18;
select age,name  from user where age >18;
  • 对查询进行优化,应考虑在 where 及 order by 涉及的列上建立索引,尽量避免全表扫描。
反例:
SELECT DISTINCT * from  user;
正例:
select DISTINCT name from user;
  • 带 distinct 的语句 CPU 时间和占用时间都高于不带 distinct 的语句。 因为当查询很多字段时,如果使用 distinct,数据库引擎就会对数据进行比较, 过滤掉重复数据,然而这个比较、过滤的过程会占用系统资源,CPU 时间。

  • 不要有超过 5 个以上的表连接。连表越多,编译的时间和开销也就越大。把连接表拆开成较小的几个执行,可读性更高。如果一定需要连接很多表才能得到数据,那么意味着糟糕的设计了。

  • 索引不宜太多,一般 5 个以内

索引并不是越多越好,索引虽然提高了查询的效率,但是也降低了插入和更新的效率。insert 或 update 时有可能会重建索引,所以建索引需要慎重考虑,视具体情况来定。一个表的索引数最好不要超过 5 个,若太多需要考虑一些索引是否没有存在的必要。

  • 相对于数字型字段,字符型会降低查询和连接的性能,并会增加存储开销。
反例:
id varchar(20) NOT NULL
正例:
id number(11) NOT NULL 
  • 相对于数字型字段,字符型会降低查询和连接的性能,并会增加存储开销。索引不适合建在有大量重复数据的字段上,如性别这类型数据库字段。因为 SQL 优化器是根据表中数据量来进行查询优化的,如果索引列有大量重复数据,查询优化器推算发现不走索引的成本更低,很可能就放弃索引了。

  • 当在 SQL 语句中连接多个表时,请使用表的别名,并把别名前缀于每一列上,这样语义更加清晰。

反例:
select  * from A inner
join B on A.deptId = B.deptId;
正例:
select  memeber.name,deptment.deptName from A member inner
join B deptment on member.deptId = deptment.deptId;
  • 为了提高 group by 语句的效率,可以在执行到该语句前,把不需要的记录过滤掉。
反例:
select job,avg(sal) from emp  group by job having job ='president' 
or job = 'managent'
正例:
select job,avg(sal) from emp where job ='president' 
or job = 'managent' group by job;

原创文章,作者:6024010,如若转载,请注明出处:https://blog.ytso.com/275217.html

(0)
上一篇 2022年7月18日
下一篇 2022年7月18日

相关推荐

发表回复

登录后才能评论