SQL 优化(1)

作者: 李逍遥JK | 来源:发表于2018-04-14 15:44 被阅读27次

    最近发现数据库sql优化对客户的体验有很大的提高。在项目中将之前的DBUtils+反射来查询的方式改变为Spring Template。效率升高了很多。因此,觉得有必要对数据库查询优化做一个总结。

    1.根据实际情况创建数据库索引

    在经常需要的字段创建索引,比如经常用到的name, id, date等字段。具体的情况根据业务确定。也可以在多个字段上创建索引

    2.使用预编译查询

    一般的后台程序是根据用户的输入执行动态SQL,这时候可能有SQL注入漏洞攻击。所以,一般要求对SQL进行预编译,并且第一次执行的时候DBMS会对其进行语句查询优化并且预编译。这样执行SQL的时候就直接使用预编译结果,提高执行的速度。

    3.调整Where语句中的连接顺序

    DBMS一般采用自下而上的的顺序解析Where字句,根据这个原理表连接最好写在其他where条件之前。并且那些过滤掉最大数量记录的条件必须写在Where子句的末尾

    4.尽量将多条SQL语句压缩到一条SQL

    每次执行SQL的时候都要建立网络连接,进行权限校验,进行SQL语句查询优化、发送执行结果,这个过程非常耗时,所以一般业务可行的条件下压缩多条语句到一条SQL语句中

    5.用Where替换having

    不要使用having,having只会在检索出所有记录之后才会对结果集进行过滤,而where实在聚合之前。having一般用于聚合函数

    6.使用表的别名

    当在SQL语句中连接多个表时,请用表的别名,并且把别名前缀到每个列名上,可以减少解析时间,避免发生列名歧义引起的错误

    7.in 和 exists 一般情况下使用exists,因为in不走索引

    8.避免在索引上使用计算

    在where子句中,如果索引是函数的一部分,DBMS的优化器将不会使用索引而使用全表查询。

         // 效率低:
    select * from person where salary*12>25000(salary是索引列)
    
      // 效率高:      
    select * from person where salary>25000/12(salary是索引列)
    

    9.用 union all 替换 union

    当SQL语句需要union两个查询结果时,一般使用union all。
    union和union all的差别就在于union会对数据做一个distanct的动作,而这个distanct动作的速度则取决于现有数据的数量,数量越大则时间也越慢。而对于几个数据集,要确保数据集之间的数据互相不重复,基本是O(n)的算法复杂度。
    UNION还有一个用处,我们在海量数据的查询中,如果使用

    select * from c_cons where cons_id in ('691339365','3387785','3387954');
    

    这样的查询语句,会引起全表扫描,可以使用UNION ALL来代替,如:

    select * from c_cons where cons_id='691339365' 
    UNION ALL 
    select * from c_cons where cons_id='3387785' 
    UNION ALL 
    select * from c_cons where cons_id='3387954'
    

    这样查询比使用in查询要快很多,它不会去进行全表扫描。

    10.避免SQL中出现隐式类型转换

    当一张表中索引字段在作为where条件的时候,如果进行了隐式类型转化,则此索引字段将不会被识别,因为隐式类型也属于计算,索引将会采用全表扫描。

    11.防止检索范围过宽

    使用is not null 或者不等于判断,可能造成优化器假设匹配的记录数太多
    使用立刻运算符的时候, "a%" 将会使用索引, 而"%a"和"%ac"则会使用全表扫面,因此"%a"和"%ac"尽量不要使用

    相关文章

      网友评论

        本文标题:SQL 优化(1)

        本文链接:https://www.haomeiwen.com/subject/zdswnxtx.html