SQL优化理解的一点方法

1、尽量避免使用select *,返回无用的字段会降低查询效率。如下:

 SELECT * FROM table 

优化方式:使用具体的字段代替*,只返回使用到的字段。

2、对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。    

3、尽量避免进行null值的判断,会导致数据库引擎放弃索引进行全表扫描。尽量避免null字段,定义时尽量使用   not null.原因是允许null时不方便查询优化,复合索引也会失效,而且如果列有索引时会额外占用空间: a int(10) NOT NULL DEFAULT 0   如下:    

SELECT * FROM table WHERE score IS NULL

优化方式:可以给字段添加默认值0,对0值进行判断。如下:

SELECT * FROM t WHERE score = 0

4、应尽量避免在where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。

MySQL只有对以下操作符才使用索引:<,<=,=,>,>=,BETWEEN,IN,以及某些时候的LIKE。 可以在LIKE操作中使用索引的情形是指另一个操作数不是以通配符(%或者_)开头的情形。

5、应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描。如下:

SELECT * FROM t WHERE id = 1 OR id = 3

 优化方式:可以用union代替or。如下:

SELECT * FROM t WHERE id = 1 UNION SELECT * FROM t WHERE id = 3

PS:如果or两边的字段是同一个,如例子中这样。貌似两种方式效率差不多,即使union扫描的是索引,or扫描的是全表)

6、尽量避免使用in 和not in,会导致数据库引擎放弃索引进行全表扫描。如下:

SELECT * FROM table WHERE id IN (3,4)

SELECT * FROM t1 WHERE username IN (SELECT username FROM t2)

 优化方式:如果是连续数值,可以用between代替。如下:   

SELECT * FROM table WHERE id BETWEEN 3 AND 4

 如果是子查询,可以用exists代替。如下:

SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t2 WHERE t1.username = t2.username)

7、尽量避免在字段开头模糊查询,会导致数据库引擎放弃索引进行全表扫描。如下:    

SELECT * FROM table WHERE username LIKE '%li%'

 优化方式:尽量在字段后面使用模糊查询。如下: 

SELECT * FROM t WHERE username LIKE 'li%'

8、尽量避免在where条件中等号的左侧进行表达式、函数操作,会导致数据库引擎放弃索引进行全表扫描。如下:   

SELECT * FROM t2 WHERE score/10 = 9

SELECT * FROM t2 WHERE SUBSTR(username,1,2) = 'li'

  优化方式:可以将表达式、函数操作移动到等号右侧。如下:

SELECT * FROM t2 WHERE score = 10*9

SELECT * FROM t2 WHERE username LIKE 'li%'

9、应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。

select id from t where substring(name,1,3)='abc'

    --name以abc开头的id应改为:

select id from t where name like 'abc%'

10、不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。如: 

select id from t where substring(name,1,3)='abc'--name
select id from t where datediff(day,createdate,'2005-11-30')=0--‘2005-11-30’

 优化方式: 

select id from t where name like 'abc%'

select id from t where createdate>='2005-11-30' and createdate<'2005-12-1'

11、在使用索引字段作为条件时,如果该索引是联合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。

12、很多时候用 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)

13、并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。

14、索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑视具体情况而定,一个表的索引数最好不要超过6个。

15、尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。

 16、尽可能的使用 varchar 代替 char ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。

17、当数据量大时,避免使用where 1=1的条件。通常为了方便拼装查询条件,我们会默认使用该条件,数据库引擎会放弃索引进行全表扫描。如下:     

SELECT * FROM t WHERE 1=1

  优化方式:用代码拼装sql时进行判断,没where加where,有where加and

18、避免频繁创建和删除临时表,以减少系统表资源的消耗。

 其实,总结起来,大家应该也发现了,就是在查询的时候,要尽量让数据库引擎使用索引。而如何让数据库按我们的意思去使用索引就涉及到扫描参数(SARG)的概念。在数据库引擎在查询分析阶段,会使用查询优化器对查询的每个阶段(如一个带子查询的sql语句就存在不同的查询阶段)进行分析,来决定需要扫描的数据量。如果一个阶段可以被用作扫描参数,那么就可以限制搜索的数据量,从而一定程度上提高搜索效率。

SARG的定义:用于限制搜索的一个操作,因为它通常是指一个特定的匹配,一个值的范围内的匹配或者两个以上条件的AND连接。

所以,我们要让我们写的查询条件尽量能够让引擎识别为扫描参数。具体做法,就如前面提到的这些方法。

转载于:https://my.oschina.net/u/2364788/blog/2873568

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值