zoukankan      html  css  js  c++  java
  • SQL优化

    SQL优化的各种误区

    1.对讹传辨知

      a)COUNT(*)与COUNT(列)

        - COUNT(*)针对全表,COUNT(列)针对列,两者不等价,无法比较其快慢。

          - 对于COUNT(列),优化器的算法是根据列的偏移量决定性能,列越靠后,访问的开销越大。COUNT(*)与偏移量无关,所以COUNT(*)最快,COUNT(最后列)最慢。

      b)SQL编写顺序

         - 表的查询顺序(针对多表查询):Oracle的解析器从右到左的顺序处理From子句中的表名,因此From子句中卸载最后的表(基础表)将被最先处理。在From子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表

        - where子句中的连接顺序:Oracle采用自下而上的顺序解析Where子句,根据这个原理,当在where子句中有多个表连接时,where子句中排在最后的表应当是返回行数可能最少的表,有过滤条件的子句应放在where子句中的最后。

         - 以上两种优化说法,基于RBO(Rule规则)确实如此。但是现在已是基于CBO(Cost代价),这些已经过时。

      c)IN与EXISTS

        - 一般来说,anti的反连接算法比filter更高效,但是在10g时,Oracle的这个算法不完善,必须要指定非空,才可以让not in用anti算法。在11g的时候,这个情况已经改变了,无论是not in 还是not exists,无论列是否为空,都可以走到Oracle比较先进高效的anti反连接算法。

    2.少做事

      a)全局临时表

        -构建基于Session的全局临时表(global temporary table t_name on commit preserve rows):退出session该表记录会自动清空

        -构建基于事务的全局临时表(global temporary table t_name on commit delete rows):commit提交后,不等退出session,该表记录就会自动清空

      b)分区表(create table t_name (columns...) partition by range(column)(partition p1 values...))

        

      c)递归函数调用

        - 避免SQL中的函数调用,可以减少消耗

        - 减少SQL中的函数调用,函数调用不要放在结果集中

      d)集合写法

      e)只取所需的列

        - 只选择需要的列,而不用*。访问视图会变更快、表连接访问提速、索引不需要回表。

      

    3.根据场景选择技术

      a)系统是个人用还是大家用?当前是忙还是闲?

      b)系统是多读还是少读?访问量是多还是少?

        - 索引的坏处:更新插入,因为索引性能会差;建索引引发锁表导致问题;建索引导致排序性能问题

        - 缓存结果集

        - 物化视图

        - 位图索引

        - Block如何设计

      c)先看表是大还是小?返回记录是多还是少?

        - 分区也会慢

        - 绑定变量居然引发故障

    4.考虑需求最小化

      a)复杂的需求抽象简单化

      b)需求有没有多余

        - 需要去重吗

        - 需要排序吗

        - 需要监控吗

    5.SQL改造等价性

      a)看似等价,其实不等价

        - insert all

    insert all
        into tmp_transaction
        into tmp_session
    select * from dba_objects;
    
    不等价于
    
    insert into tmp_transaction as select * from dba_objects;
    insert into tmp_session as select * from dba_objects;

        

        - select max(), min()

    select min(object_id), max(object_id) from t;
    不等价于
    select max(object_id) from t;
    select min(object_id) from t;
    
    
    select min(object_id), max(object_id) from t;
    等价于
    select max,min from (select max(object_id) max from t) a,
    (select min(object_id) min from t) b;

        - in与><范围

        - count(*)与count(列)

      b)看似不等价,其实等价

        -关于表是否有记录的判断

    6.需求是顶级优化(需求优化)

      a)需求优化需要不断的考虑

        - 界面权限设计优化(并非所有操作都需要做权限判定)

        - 界面实时刷新改良(先显示汇总,再由用户点击展示)

        - 单脚本对应多指示(不但多采集,还要去屏蔽规则)

        - 表单展示的异步载入(界面内容自上而下逐步展现)

      b)如下问答解决了很多性能问题

        - 排序有必有吗

        - 历史数据要保留多久

        - 这个需求过时了吗

        - 采集频率真要如此频繁吗

    7.发现问题方法论

      a)先判断后动手

        - 故障未解决:备份相关证据、收集日志;分析主要矛盾,解决问题

        - 故障已消除:分析系统的日志,了解故障的时段

      b)先动态后静态

      c)先整体后局部


    未完,待续。。。。。

  • 相关阅读:
    我的知识库(4) java获取页面编码(Z)
    知识库(3)JAVA 正则表达式 (超详细)
    The Struts dispatcher cannot be found. This is usually caused by using Struts tags without the associated filter. Struts
    某人总结的《英语听力的技巧 》,挺搞的
    我的知识库(5)java单例模式详解
    构建可扩展程序
    SerialPort (RS232 Serial COM Port) in C# .NET
    Python学习笔记——String、Sequences
    UI题目我的答案
    jQuery学习系列学会操纵Form表单元素(1)
  • 原文地址:https://www.cnblogs.com/konrad/p/6481472.html
Copyright © 2011-2022 走看看