除了索引之外,如何优化 sql 代码?

Posted

技术标签:

【中文标题】除了索引之外,如何优化 sql 代码?【英文标题】:How can I optimize sql code beside to indexing? 【发布时间】:2019-01-17 11:22:13 【问题描述】:

我写了一个如下的 sql 代码。后来根据where条件添加了一些索引,但是性能还不够。 sql有没有一般的优化规则或者下面的sql有什么建议?如何改进我的 sql 代码?

    SELECT COUNT(*) OVER() AS tot_count,
    PG.DESCR as partner, 
    THAF.APPDATA 
    FROM   transhist th, 
    trans_app thaf, 
    partnergroup pg, 
    partnergrpkey pgk 

    WHERE TH.CreateDt >= to_date('?startdate', 'yyyymmddhh24mi') 
    AND TH.CreateDt <= to_date('?enddate', 'yyyymmddhh24mi')+1/1440 


    AND TH.TRANSSET = '820' 
    AND THAF.TRANSHISTID = th.id 
    AND THAF.COLUMNID = 74 

    AND THAF.APPDATA LIKE '%|?acctNo|%' 

    AND TH.TRNSLTPARTNERKEY = PGK.DOCHISTPARTNERKEY 
    AND PG.ID = PGK.PARTNERGROUPID 

    AND pg.ID IN (?tpValues) 


    ORDER BY TH.ID;

索引如下:

CREATE INDEX TRANS_APP_ALL ON TRANS_APP(TRANSHISTID, COLUMNID, APPDATA);
CREATE INDEX TRANS_CREATEDT ON TRANSHIST(TRANSSET, CREATEDT, TRNSLTPARTNERKEY);

【问题讨论】:

今日提示:始终使用现代、明确的JOIN 语法。更容易编写(没有错误),更容易阅读和维护,如果需要更容易转换为外连接! (与优化无关。) 很难说,因为你的问题类似于“我有一辆蓝色的车,很慢。为什么?”。性能调优不是一项简单的任务,它取决于很多事情。有书籍写过它,所以...尝试从头开始,从单个表(最大的表)中选择。让它尽可能快地工作,(重新)查看解释计划输出。然后添加另一个表,检查解释计划,如果可能的话对其进行调整。等等。希望你会成功。 “sql有什么通用的优化规则吗?” 如果有专门做Oracle性能调优的顾问,是收不到他们收取的高额费用的。请阅读@marmitebomber 关于询问 Oracle 性能调优问题的出色说明。 Find it here。它说明了我们需要多少信息才能提出有用的建议(而不是盲目猜测)。 顺便说一下,使用 ANSi 92 显式连接语法并没有提高性能。就我个人而言,我觉得它更清楚,但我认识几个 Oracle 资深人士,他们一直使用旧语法,而对代码效率没有任何影响。在这个网站上,它的主要好处是,如果你不写明确的连接,某些人会因为使用旧语法而责备你。 对,@APC - 如果它关于汽车的,解决办法就是把它涂成红色。因为它是关于计算机的,所以解决方案是按下 TURBO 按钮。 【参考方案1】:

首先,使用正确、明确、标准 join 语法编写查询:

select count(*) over () AS tot_count,
       PG.DESCR as partner, 
       THAF.APPDATA 
from transhist th join 
     partnergrpkey pgk 
     on TH.TRNSLTPARTNERKEY = PGK.DOCHISTPARTNERKEY join
     partnergroup pg
     on PG.ID = PGK.PARTNERGROUPID join
     trans_app thaf
     on THAF.TRANSHISTID = th.id
where TH.CreateDt >= to_date('?startdate', 'yyyymmddhh24mi') and
      TH.CreateDt <= to_date('?enddate', 'yyyymmddhh24mi')+1/1440 and
      TH.TRANSSET = '820' and
      THAF.COLUMNID = 74 and
      THAF.APPDATA LIKE '%|?acctNo|%' and
      pg.ID IN (?tpValues) 
order by TH.ID;

对于这个查询,我希望以下索引会有所帮助:

transhist(TRANSSET, CreateDt, TRNSLTPARTNERKEY, id) partnergrpkey(DOCHISTPARTNERKEY, PARTNERGROUPID) partnergroup(id) trans_app(TRANSHISTID, COLUMNID, APPDATA)

这些与您拥有的索引相似。您可能需要检查执行计划以查看索引是否实际被使用。

【讨论】:

Gordon,鉴于没有关于基数等的信息,您为什么认为这些索引会有所帮助?

以上是关于除了索引之外,如何优化 sql 代码?的主要内容,如果未能解决你的问题,请参考以下文章

mysql中的索引优化

MySQL索引与优化

sql查询优化 索引优化

索引原理与数据库优化

MySQL索引,SQL优化一网打尽

MySQL索引,SQL优化一网打尽