sql优化点总结
2017-10-15 15:08
176 查看
引起db全表扫描的情况和优化策略
1、模糊查询:
like 效率很低,而且右like模块查询,是无法使用索引的,反而会引起全表扫描,
左like是可以使用全表扫描的
2、避免在where中使用is null或 is not null
null对于大多数数据库需要特殊处理,需要更多的代码检查逻辑,有些开发人员没有意识到,创建表null是默认值
但大多数时候应该使用not null,或者使用一个特殊的值,比如0/1或者-1作为默认值。
同时索引中也不会包含null值,如果多个索引列中有一列数据包含null值,则该列就会被从索引中除去,
即:如果该列存在null值,即使对该列创建索引也不会提高性能。
3、避免在where子句中使用!= 或者 <>操作符,否则引擎则放弃索引进行全表扫描
如:where num <> 100 可以改成 where num <100 or num > 100
4、减少explain
myisam存储引擎对count(*)做了优化,故效率很快。
select count(*) from user where id > 5; 如果有100000条数据的话,就会扫描10000-5行数据
select (select count(*) from user) - count(*) from user where id <=5; 这样就只会有5次explain
5、建立索引
确保在on或using使用的列上建立索引
通常只需要在连接的第二个表上字段列建立索引
6、避免使用*: * 会增加额外时间来查询数据库表中的所有字段名
7、记录数最少的表放到from的最后,因为会先解析最右边的表
8、用Exist 和 not exist 代替IN和NOT IN,因为in会执行一个全表扫描,并对结果集进行合并和排序,效率最低
9、用exist代替distinct
如:(低效):
SELECT DISTINCT DEPT_NO,DEPT_NAME FROM DEPT D , EMP E
WHERE D.DEPT_NO = E.DEPT_NO
(高效):
SELECT DEPT_NO,DEPT_NAME FROM DEPT D WHERE EXISTS ( SELECT ‘X’
FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO);
10、 用>=替代>
如:高效:
SELECT * FROM EMP WHERE DEPTNO >=4
低效:
SELECT * FROM EMP WHERE DEPTNO >3
两者的区别在于, 前者DBMS将直接跳到第一个DEPT等于4的记录而后者将首先定位到DEPTNO=3的记录 并且向前扫描到第一个DEPT大于3的记录.
11、应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描
如:select id from t where num=10 or num=20
可以这样查询:
select id from t where num=10
union all
select id from t where num=20
12、select id from t where num=10 or num=20
可以这样查询:
select id from t where num=10
union all
select id from t where num=20
13、应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:
select id from t where substring(name,1,3)='abc'--name以abc开头的id
select id from t where datediff(day,createdate,'2005-11-30')=0--'2005-11-30'生成的id
应改为:
select id from t where name like 'abc%'
select id from t where createdate>='2005-11-30' and createdate<'2005-12-1'
1、模糊查询:
like 效率很低,而且右like模块查询,是无法使用索引的,反而会引起全表扫描,
左like是可以使用全表扫描的
2、避免在where中使用is null或 is not null
null对于大多数数据库需要特殊处理,需要更多的代码检查逻辑,有些开发人员没有意识到,创建表null是默认值
但大多数时候应该使用not null,或者使用一个特殊的值,比如0/1或者-1作为默认值。
同时索引中也不会包含null值,如果多个索引列中有一列数据包含null值,则该列就会被从索引中除去,
即:如果该列存在null值,即使对该列创建索引也不会提高性能。
3、避免在where子句中使用!= 或者 <>操作符,否则引擎则放弃索引进行全表扫描
如:where num <> 100 可以改成 where num <100 or num > 100
4、减少explain
myisam存储引擎对count(*)做了优化,故效率很快。
select count(*) from user where id > 5; 如果有100000条数据的话,就会扫描10000-5行数据
select (select count(*) from user) - count(*) from user where id <=5; 这样就只会有5次explain
5、建立索引
确保在on或using使用的列上建立索引
通常只需要在连接的第二个表上字段列建立索引
6、避免使用*: * 会增加额外时间来查询数据库表中的所有字段名
7、记录数最少的表放到from的最后,因为会先解析最右边的表
8、用Exist 和 not exist 代替IN和NOT IN,因为in会执行一个全表扫描,并对结果集进行合并和排序,效率最低
9、用exist代替distinct
如:(低效):
SELECT DISTINCT DEPT_NO,DEPT_NAME FROM DEPT D , EMP E
WHERE D.DEPT_NO = E.DEPT_NO
(高效):
SELECT DEPT_NO,DEPT_NAME FROM DEPT D WHERE EXISTS ( SELECT ‘X’
FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO);
10、 用>=替代>
如:高效:
SELECT * FROM EMP WHERE DEPTNO >=4
低效:
SELECT * FROM EMP WHERE DEPTNO >3
两者的区别在于, 前者DBMS将直接跳到第一个DEPT等于4的记录而后者将首先定位到DEPTNO=3的记录 并且向前扫描到第一个DEPT大于3的记录.
11、应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描
如:select id from t where num=10 or num=20
可以这样查询:
select id from t where num=10
union all
select id from t where num=20
12、select id from t where num=10 or num=20
可以这样查询:
select id from t where num=10
union all
select id from t where num=20
13、应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:
select id from t where substring(name,1,3)='abc'--name以abc开头的id
select id from t where datediff(day,createdate,'2005-11-30')=0--'2005-11-30'生成的id
应改为:
select id from t where name like 'abc%'
select id from t where createdate>='2005-11-30' and createdate<'2005-12-1'
相关文章推荐
- 解析Oracle数据扫描 Oracle SQL查询优化 总结篇
- 数据库SQL优化大总结之 百万级数据库优化方案
- Oracle SQL性能优化技巧大总结
- 数据库SQL优化大总结之 百万级数据库优化方案
- ORACLE EXPLAIN PLAN的总结 (优化SQL语句)
- 数据库SQL优化大总结之 百万级数据库优化方案
- mysql-SQL优化总结
- 数据库SQL优化大总结之 百万级数据库优化方案
- sql优化总结
- 数据库SQL优化大总结之百万级数据库优化方案
- 面试总结-SQL优化
- SQL 优化经验总结34条
- SQL 语句 优化系列总结
- 数据库SQL优化大总结之 百万级数据库优化方案
- SQL优化经验总结
- mysql数据库sql优化原则(经验总结)
- Oracle SQL优化 总结(学习)(转)
- SQL语句级别的优化总结
- MYSQL语句调优:SQL优化总结
- 通过分析SQL语句的执行计划优化SQL(总结)