美文网首页Java 杂谈Java交流
自己遇到的一些SQL优化

自己遇到的一些SQL优化

作者: 周小鑫001 | 来源:发表于2019-02-26 16:54 被阅读0次

    字符的分隔

    (思想,先构造在拼接)

    SELECTa.id,b.NAME,A.WORK_TYPE,b."ID"

    FROMCRD.T_CRD_SCORE_CONFIGa

    leftJOINEMERP.T_BASE_WORK_TYPE_ALLbon','||A.WORK_TYPE||','like'%,'||b.id||',%'GROUPBYA.ID

    分组函数:GROUP BY

      分组函数,可以多次分组

      提高GROUP BY 语句的效率,可以通过将不需要的记录在GROUP BY 之前过滤掉

    子查询

       这次写代码的时候,有一些字段上线前着急要和实际的业务逻辑,使用了子查询,有的可以使用连接查询,但是没有优化

    记录的标记字段

    这次编写代码的时候,标记这条记录是否删除,使用,显示,在编写SQL的时候出现了一些漏写的字段,以后再写的时候,一定要注意全

    表空间(用户)

    在编写SQL的时候,没有注意在表前标记空间名(用户)。

    OR的使用

    OR一定要合理运用,总忘记这个

    ORDER BY 的使用

    1. 只有ORDER BY 子句中可以使用select列表中列的别名

    2. 使用了ORDER BY子句的查询不能用作表表达式(视图、内联表值函数、子查询、派生表和共用表达式)

    3. 在分页的时候,如果是多表连接的,要是条件排序的条件的值一致,在分页的时候可能两次的结果有重复数据。

    exts和in用法

    1. exists对外表做循环,每次循环对内表查询;in将内表和外表做hash连接

    2. 使用exists oracle会先检查主查询,使用in,首先执行子查询,将结果存储在临时表中

    3. 如果两个表大小相当,in和exists差别不大

    4. 如果两个表大小相差较大则子查询表大的用exists,子查询表小的用in

    5.尽量不要使用not in

    union和union all

      1. 使用场景:需要将两个select语句结果整体显示时,可以使用union和unionall

    2.union对两个结果集取并集不包含重复结果同时进行默认规则的排序;而union all对两个结果集去并集,包括  重复行,不进行排序

      3.union需要进行重复值扫描,效率低,如果没有要删除重复行,应该使用union all

      4.insersect和minus分别交集和差集,都不包括重复行,并且进行默认规则的排序

     5.可以将多个结果集合并

      6.必须保证select集合的结果有相同个数的列,并且每个列的类型是一样的(列名不一定要相同,会默认将第一个结果的列名作为结果集的列名)

    指定where的条件顺序

    1. 默认情况下,Oracle采用自下而上的顺序解析where字句,因此在处理多表查询的时候,表之间的连接必须写在其他的where条件之前,但是过滤数据记录的条件则必须写在where子句的尾部,以便在过滤了数据之后再进行连接处理,这样可以提升sql语句的性能

    LEFT--JOIN  注释事项

    在使用left-join的时候一定要注意顺序问题。

    SQL语句尽量用大写的

    因为oracle总是先解析SQL语句,把小写的字母转换成大写的再执行。

    使用表的别名

        当在SQL语句中连接多个表时, 尽量使用表的别名并把别名前缀于每个列上。这样一来,就可以减少解析的时间并 减少那些由列歧义引起的语法错误。

    选择最有效率的表名顺序(只在基于规则的优化器(RBO)中有效)

      ORACLE 的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表也称为驱动表,driving table)将被最先处理,在FROM子句中包含多个表的情况下,必须选择记录条数最少的表作为基础表。如果有3个以上的表连接查询, 那就需要选择交叉表(intersection table)作为基础表, 交叉表是指那个被其他表所引用的表。

    避免使用耗费资源的操作

     带有DISTINCT、UNION、MINUS、INTERSECT、ORDER BY的SQL语句会启动SQL引擎执行

    耗费资源的排序(SORT)功能。DISTINCT需要一次排序操作,而其他的至少需要执行两次排序。

    通常,带有UNION、MINUS、INTERSECT的SQL语句都可以用其他方式重写。

     如果数据库的SORT_AREA_SIZE调配得好,使用UNION,MINUS,INTERSECT也是可以考虑。 

    用Where子句替换HAVING子句

        避免使用HAVING子句,HAVING只会在检索出所有记录之后才对结果集进行过滤。这个处理需要排序,总计等操作。最好能通过WHERE子句限制记录的数目。(非oracle中)on、where、having这三个都可以加条件的子句中,on是最先执行,where次之,having最后。

    避免在索引列上使用计算

      WHERE子句中,如果索引列是函数的一部分,优化器将不使用索引而使用全表扫描。

    BETWEEN    AND

    取值是两边都要。

    NVL2(expr1,expr2,expr3)

    NVL2(表达式,不为空设值,为空设值)

    to_char用法

    (1)用作日期转换

        to_char(date,'格式');

        select to_char(sysdate,'yyyy-MM-dd HH24:mi:ss') from dual;

    (2)处理数字

        to_char(number,'格式');

         select to_char(88877) from dual;

         select to_char(1234567890,'099999999999999')  from dual;

         select to_char(12345678,'999,999,999,999')  from dual;

         select to_char(123456,'99.999')  from dual;

         select to_char(1234567890,'999,999,999,999.9999')  from dual;

    (3) 处理钱

        to_char(salary,'$99,99');

      select TO_CHAR(123,'$99,999.9') from dual;

    (4)用于进制转换:将10进制转换为16进制;

        select to_char(4567,'xxxx') from dual;

        select to_char(123,'xxx') from dual;

    to_date

    select sysdate,to_date('20170615','yyyymmdd')from dual;

    select sysdate,to_date('20170615','yyyy-mm-dd')from dual;

    select sysdate,to_date('20170615','yyyy/mm/dd')from dual;

    select sysdate,to_date('20170615','yyyy-mm-dd hh24:mi:ss')from dual;

    应尽量避免在 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'

    模糊查询

    当模糊匹配以%开头时,该列索引将失效,若不以%开头,该列索引有效。

    常用函数

    FLOOR(x)   返回小于x的最大整数值

    AVG(col)返回指定列的平均值

    COUNT(col)返回指定列中非NULL值的个数

    MIN(col)返回指定列的最小值

    MAX(col)返回指定列的最大值

    SUM(col)返回指定列的所有值之和

    LEFT(str,x)返回字符串str中最左边的x个字符

    TRIM(str)去除字符串首部和尾部的所有空格

    UCASE(str)或UPPER(str) 返回将字符串str中所有字符转变为大写后的结果

    优化总结口诀

    ​ 全值匹配我最爱,最左前缀要遵守;

    ​ 带头大哥不能死,中间兄弟不能断;

    ​        索引列上少计算,范围之后全失效;

    ​ LIKE百分写最右,覆盖索引不写星;

    ​ 不等空值还有or,  索引失效要少用;

    ​        VAR引号不可丢,SQL高级也不难;

    如何分析SQL

    1.观察,至少跑一天,看看生产的慢SQL情况。

    2.开启慢查询日志,设置阀值,比如超过5秒钟就是慢SQL,并将它抓取出来

    3.explain+慢SQL分析

    4.show profile

    5.DBA进行SQL数据库服务器的参数调优

    总结:

    1.慢查询的开启并捕获

    2.explain+慢SQL分析

    3.show profile查询SQL在MySql里面的执行细节和生命周期情况

    4.SQl数据服务器的参数调优

    相关文章

      网友评论

        本文标题:自己遇到的一些SQL优化

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