SQL优化

使用索引的优化

索引一般可以加速数据的检索速度,加速表与表之间的链接,提高性能,所以在对海量数据进行处理时,考虑到信息量比较大,应该对表建立索引,包括在主键上建立聚簇索引,将聚合索引建立在日期上等。索引的优点有很多,但是对于索引的建立,还需要考虑实际情况,而不是对每一个列建立一个索引,比如针对大表的分组、排序等字段,都要建立相应索引,同时还应该考虑建立符合索引。增加索引的同时也有很多不好的方面,首先,创建索引和维护索引都耗费时间,且随着数据量的增加而增加;其次,索引占据物理空间,聚簇索引的空间更大。最后,当对表进行增加、删除和修改的时候,索引也要动态的维护。所以索引的引用有以下几个原则:

(1)当插入数据为表中数据的百分之10以上时,首先需要删除该表的索引来提高数据的插入效率,然后再重新建立索引;

(2)避免在索引列上使用函数或计算或类型转换,在where字句中,如果索引是函数的一部分,优化器将不再使用索引,将使用全表扫描;例如:

select * from table where hh*10>1000;//低效
select * from table where hh>1000/10;//更高效

(3)尽量避免在索引列上使用not,!=和<>,索引只能告诉什么在表中,而不能告诉什么不在表中,当数据库遇上以上几种符号时,将不再使用索引,使用全表扫描

(4)最佳左前缀法则:最佳左前缀法则指的是查询从索引的最左侧开始,并且不跳过中间列,用通俗的话来说就是:带头大哥不能死、中间兄弟不能断。比如我们建立了id\name\class三个字段的复合索引,但是在查询中,并没有查询id,只查询了name或class,这时索引失效;或者我们在查询中查询了id和class字段却没有使用name字段,也会使索引部分失效。

(5)避免在索引列上使用IS NULL 或 IS NOT NULL。避免在索引列上使用任何可以为空的列,这样将无法使用此索引。因为空值不存在于索引列中,所以当where字句中对索引进行空值比较,将无法使用该索引。

(6)在索引列上,使用>=代替>,比如:

select * from table where hh>10;//低效
select * from table where hh>=10.0000001//相对高效

(7)应尽量避免在 where 子句中使用 or 来连接条件,如果一个字段有索引,一个字段没有索引,将导致引擎放弃使用索引而进行全表扫描,如:

select id from t where num=10 or Name = 'admin'

可以这样查询:

select id from t where num = 10
union all
select id from t where Name = 'admin'

(8) 在使用LIKE关键字进行查询的查询语句中,如果匹配字符串的第一个字符为“%”,索引不会起作用。只有“%”不在第一个位置索引才会起作用。如:

select id from t where Name like '%abc%' //低效

select id from t where Name like 'abc%' //高效

sql的优化

(1)select的时候要将需要的字段全部列出,而不是使用*代替,例如:

select * from student//低效

select id,name,class from student   //高效

(2)多表查询时最好给表取别名,这样一来,就可以减少解析的时间并减少那些由Column歧义引起的语法错误

(3)有条件的使用union-all代替union提高效率

(4)用exists代替in,可以提高查询的效率,对于连续的数值,能用 between 就不要用 in。例如:

SELECT * FROM ACCOUNT
    WHERE AC_CODE 
    NOT IN (
              SELECT CODE
              FROM GOODS
              WHERE NUM='001')       //低效

SELECT * FROM ACCOUNT
    WHERE NOT EXISTSSELECT CODE
          FROM GOODS
          WHERE CODE=ACCOUNT.AC_CODE
           AND NUM='001')             //更高效
           

(5)where字句中的链接顺序

oracle采用自下而上的顺序解析where字句,所以表之间的链接必须写在其他where条件之前,那些可以滤过大量纪录的条件必须写在where字句的末尾,例如:

select * from table e
      where h>500     
                  and d='001'
                  and 25<(select count(*) 
                               from table 
                               where count=e.count);  //低效

select * from table e
      where  25<(select count(*) 
                          from table 
                          where count=e.count);    
                   and  h>500
                   and d='001';//更高效     

(6)where条件里尽量不要进行null值的判断,null的判断也会造成全表扫描。如下:

SELECT * FROM t_order WHERE score IS NULL

优化:

给字段添加默认值,对默认值进行判断。如:

SELECT * FROM t_order WHERE score = 0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值