上海的一个哥们问我有个SQL跑了4个小时都没跑完,实在受不了了,找我优化一下。我确实挺佩服他的,要是我遇到跑了几分钟的,就受不了了。

SQL语句和执行计划如下:

--sql id:1qbbw3th4x8yc

SELECT "VOUCHER".FID "ID",

       "ENTRIES".FID "ENTRIES.ID",

       "ENTRIES".FEntryDC "ENTRIES.ENTRYDC",

       "ACCOUNT".FID "ACCOUNT.ID",

       "ENTRIES".FCurrencyID "CURRENCY.ID",

       "PERIOD".FNumber "PERIOD.NUMBER",

       "ENTRIES".FSeq "ENTRIES.SEQ",

       "ENTRIES".FLocalExchangeRate "LOCALEXCHANGERATE",

       "ENTRIES".FReportingExchangeRate "REPORTINGEXCHANGERATE",

       "ENTRIES".FMeasureUnitID "ENTRYMEASUREUNIT.ID",

       "ASSISTRECORDS".FID "ASSISTRECORDS.ID",

       "ASSISTRECORDS".FSeq "ASSISTRECORDS.SEQ",

       CASE

         WHEN (("ACCOUNT".FCAA IS NULL) AND

              ("ACCOUNT".FhasUserProperty <> 1)) THEN

          "ENTRIES".FOriginalAmount

         ELSE

          "ASSISTRECORDS".FOriginalAmount

       END "ASSISTRECORDS.ORIGINALAMOUNT",

       CASE

         WHEN (("ACCOUNT".FCAA IS NULL) AND

              ("ACCOUNT".FhasUserProperty <> 1)) THEN

          "ENTRIES".FLocalAmount

         ELSE

          "ASSISTRECORDS".FLocalAmount

       END "ASSISTRECORDS.LOCALAMOUNT",

       CASE

         WHEN (("ACCOUNT".FCAA IS NULL) AND

              ("ACCOUNT".FhasUserProperty <> 1)) THEN

          "ENTRIES".FReportingAmount

         ELSE

          "ASSISTRECORDS".FReportingAmount

       END "ASSISTRECORDS.REPORTINGAMOUNT",

       CASE

         WHEN (("ACCOUNT".FCAA IS NULL) AND

              ("ACCOUNT".FhasUserProperty <> 1)) THEN

          "ENTRIES".FQuantity

         ELSE

          "ASSISTRECORDS".FQuantity

       END "ASSISTRECORDS.QUANTITY",

       CASE

         WHEN (("ACCOUNT".FCAA IS NULL) AND

              ("ACCOUNT".FhasUserProperty <> 1)) THEN

          "ENTRIES".FStandardQuantity

         ELSE

          "ASSISTRECORDS".FStandardQuantity

       END "ASSISTRECORDS.STANDARDQTY",

       CASE

         WHEN (("ACCOUNT".FCAA IS NULL) AND

              ("ACCOUNT".FhasUserProperty <> 1)) THEN

          "ENTRIES".FPrice

         ELSE

          "ASSISTRECORDS".FPrice

       END "ASSISTRECORDS.PRICE",

       CASE

         WHEN ("ACCOUNT".FCAA IS NULL) THEN

          NULL

         ELSE

          "ASSISTRECORDS".FAssGrpID

       END "ASSGRP.ID"

  FROM T_GL_Voucher "VOUCHER"

  LEFT OUTER JOIN T_BD_Period "PERIOD"

    ON "VOUCHER".FPeriodID = "PERIOD".FID

 INNER JOIN T_GL_VoucherEntry "ENTRIES"

    ON "VOUCHER".FID = "ENTRIES".FBillID

 INNER JOIN T_BD_AccountView "ACCOUNT"

    ON "ENTRIES".FAccountID = "ACCOUNT".FID

  LEFT OUTER JOIN T_GL_VoucherAssistRecord "ASSISTRECORDS"

    ON "ENTRIES".FID = "ASSISTRECORDS".FEntryID

 WHERE "VOUCHER".FID IN

       (SELECT "VOUCHER".FID "ID"

          FROM T_GL_Voucher "VOUCHER"

         INNER JOIN T_GL_VoucherEntry "ENTRIES"

            ON "VOUCHER".FID = "ENTRIES".FBillID

         INNER JOIN T_BD_AccountView "ACCOUNT"

            ON "ENTRIES".FAccountID = "ACCOUNT".FID

         INNER JOIN t_bd_accountview PAV

            ON ((INSTR("ACCOUNT".flongnumber, pav.flongnumber) = 1 AND

               pav.faccounttableid = "ACCOUNT".faccounttableid) AND

               pav.fcompanyid = "ACCOUNT".fcompanyid)

         WHERE (("VOUCHER".FCompanyID IN ('fSSF82rRSKexM3KKN1d0tMznrtQ=')) AND

               (("VOUCHER".FBizStatus IN (5)) AND

               ((("VOUCHER".FPeriodID IN ('+wQxkBFVRiKnV7OniceMDoI4jEw=')) AND

               "ENTRIES".FCurrencyID =

               'dfd38d11-00fd-1000-e000-1ebdc0a8100dDEB58FDC') AND

               (pav.FID IN ('vyPiKexLRXiyMb41VSVVzJ2pmCY='))))))

 ORDER BY "ID" ASC, "ENTRIES.SEQ" ASC, "ASSISTRECORDS.SEQ" ASC

--执行计划

--------------------------------------------------------------------------------------------------------

| Id  | Operation                              | Name                     | Rows  | Bytes | Cost (%CPU)|

--------------------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT                       |                          |    13 |  5733 |   486   (1)|

|   1 |  SORT ORDER BY                         |                          |    13 |  5733 |   486   (1)|

|   2 |   VIEW                                 | VM_NWVW_2                |    13 |  5733 |   486   (1)|

|   3 |    HASH UNIQUE                         |                          |    13 | 11115 |   486   (1)|

|   4 |     NESTED LOOPS OUTER                 |                          |    13 | 11115 |   485   (1)|

|   5 |      NESTED LOOPS                      |                          |     9 |  6606 |   471   (1)|

|   6 |       NESTED LOOPS                     |                          |     9 |  6057 |   467   (1)|

|   7 |        MERGE JOIN OUTER                |                          |     1 |   473 |   459   (1)|

|   8 |         HASH JOIN                      |                          |     1 |   427 |   458   (1)|

|   9 |          NESTED LOOPS                  |                          |       |       |            |

|  10 |           NESTED LOOPS                 |                          |   258 | 83850 |   390   (0)|

|  11 |            NESTED LOOPS                |                          |     6 |  1332 |     3   (0)|

|  12 |             TABLE ACCESS BY INDEX ROWID| T_BD_ACCOUNTVIEW         |     1 |   111 |     2   (0)|

|  13 |              INDEX UNIQUE SCAN         | PK_BD_ACCOUNTVIEW        |     1 |       |     1   (0)|

|  14 |             INDEX RANGE SCAN           | IX_BD_ACTCOMLNUM         |     6 |   666 |     1   (0)|

|  15 |            INDEX RANGE SCAN            | IX_GL_VCHAACCT           |   489 |       |     1   (0)|

|  16 |           TABLE ACCESS BY INDEX ROWID  | T_GL_VOUCHERENTRY        |    42 |  4326 |    65   (0)|

|  17 |          INDEX RANGE SCAN              | IX_GL_VCH_11             |  7536 |   750K|    68   (0)|

|  18 |         BUFFER SORT                    |                          |     1 |    46 |   391   (0)|

|  19 |          INDEX RANGE SCAN              | IX_PERIOD_ENC            |     1 |    46 |     1   (0)|

|  20 |        TABLE ACCESS BY INDEX ROWID     | T_GL_VOUCHERENTRY        |    17 |  3400 |     8   (0)|

|  21 |         INDEX RANGE SCAN               | IX_GL_VCHENTRYFQ1        |    17 |       |     1   (0)|

|  22 |       TABLE ACCESS BY INDEX ROWID      | T_BD_ACCOUNTVIEW         |     1 |    61 |     1   (0)|

|  23 |        INDEX UNIQUE SCAN               | PK_BD_ACCOUNTVIEW        |     1 |       |     1   (0)|

|  24 |      TABLE ACCESS BY INDEX ROWID       | T_GL_VOUCHERASSISTRECORD |     1 |   121 |     2   (0)|

|  25 |       INDEX RANGE SCAN                 | IX_GL_VCHASSREC_11       |     2 |       |     1   (0)|

--------------------------------------------------------------------------------------------------------

Note

-----

   - 'PLAN_TABLE' is old version

我靠 plan_table is old version....一般遇到这种执行计划发给我 我是理都不理的,但是 这哥们关系好,算了吧 勉为其难。

那我就不从执行计划 入手优化了,直接分析sql语句优化。这个sql挺简单的,from 后面几个表, where 有个 in ,最后有个order by

问他 in 后面返回多少记录

落落  17:11:46



你先看 where in 里面跑多久

上海-咖啡迷  17:12:40

很快

23s 16880rows

其他表大小如下


看到这些就知道怎么优化了 。之前跑4个小时不出结果,那行嘛 我给你优化到1分钟

in 只返回16880条数据,那么可以用in作为驱动表去驱动 T_GL_Voucher

思路 就跟 这个博客一样的 http://blog.csdn.net/robinson1988/article/details/10551467 我靠 居然还个sb在乱评论

因为in里面有点复杂,不好用hint,我偷懒,难得去搞了,直接 用下面的sql 优化

with x as  (SELECT  /*+ materialize */  "VOUCHER".FID "ID"

          FROM T_GL_Voucher "VOUCHER"

         INNER JOIN T_GL_VoucherEntry "ENTRIES"

            ON "VOUCHER".FID = "ENTRIES".FBillID

         INNER JOIN T_BD_AccountView "ACCOUNT"

            ON "ENTRIES".FAccountID = "ACCOUNT".FID

         INNER JOIN t_bd_accountview PAV

            ON ((INSTR("ACCOUNT".flongnumber, pav.flongnumber) = 1 AND

               pav.faccounttableid = "ACCOUNT".faccounttableid) AND

               pav.fcompanyid = "ACCOUNT".fcompanyid)

         WHERE (("VOUCHER".FCompanyID IN ('fSSF82rRSKexM3KKN1d0tMznrtQ=')) AND

               (("VOUCHER".FBizStatus IN (5)) AND

               ((("VOUCHER".FPeriodID IN ('+wQxkBFVRiKnV7OniceMDoI4jEw=')) AND

               "ENTRIES".FCurrencyID =

               'dfd38d11-00fd-1000-e000-1ebdc0a8100dDEB58FDC') AND

               (pav.FID IN ('vyPiKexLRXiyMb41VSVVzJ2pmCY='))))))

SELECT "VOUCHER".FID "ID",

       "ENTRIES".FID "ENTRIES.ID",

       "ENTRIES".FEntryDC "ENTRIES.ENTRYDC",

       "ACCOUNT".FID "ACCOUNT.ID",

       "ENTRIES".FCurrencyID "CURRENCY.ID",

       "PERIOD".FNumber "PERIOD.NUMBER",

       "ENTRIES".FSeq "ENTRIES.SEQ",

       "ENTRIES".FLocalExchangeRate "LOCALEXCHANGERATE",

       "ENTRIES".FReportingExchangeRate "REPORTINGEXCHANGERATE",

       "ENTRIES".FMeasureUnitID "ENTRYMEASUREUNIT.ID",

       "ASSISTRECORDS".FID "ASSISTRECORDS.ID",

       "ASSISTRECORDS".FSeq "ASSISTRECORDS.SEQ",

       CASE

         WHEN (("ACCOUNT".FCAA IS NULL) AND

              ("ACCOUNT".FhasUserProperty <> 1)) THEN

          "ENTRIES".FOriginalAmount

         ELSE

          "ASSISTRECORDS".FOriginalAmount

       END "ASSISTRECORDS.ORIGINALAMOUNT",

       CASE

         WHEN (("ACCOUNT".FCAA IS NULL) AND

              ("ACCOUNT".FhasUserProperty <> 1)) THEN

          "ENTRIES".FLocalAmount

         ELSE

          "ASSISTRECORDS".FLocalAmount

       END "ASSISTRECORDS.LOCALAMOUNT",

       CASE

         WHEN (("ACCOUNT".FCAA IS NULL) AND

              ("ACCOUNT".FhasUserProperty <> 1)) THEN

          "ENTRIES".FReportingAmount

         ELSE

          "ASSISTRECORDS".FReportingAmount

       END "ASSISTRECORDS.REPORTINGAMOUNT",

       CASE

         WHEN (("ACCOUNT".FCAA IS NULL) AND

              ("ACCOUNT".FhasUserProperty <> 1)) THEN

          "ENTRIES".FQuantity

         ELSE

          "ASSISTRECORDS".FQuantity

       END "ASSISTRECORDS.QUANTITY",

       CASE

         WHEN (("ACCOUNT".FCAA IS NULL) AND

              ("ACCOUNT".FhasUserProperty <> 1)) THEN

          "ENTRIES".FStandardQuantity

         ELSE

          "ASSISTRECORDS".FStandardQuantity

       END "ASSISTRECORDS.STANDARDQTY",

       CASE

         WHEN (("ACCOUNT".FCAA IS NULL) AND

              ("ACCOUNT".FhasUserProperty <> 1)) THEN

          "ENTRIES".FPrice

         ELSE

          "ASSISTRECORDS".FPrice

       END "ASSISTRECORDS.PRICE",

       CASE

         WHEN ("ACCOUNT".FCAA IS NULL) THEN

          NULL

         ELSE

          "ASSISTRECORDS".FAssGrpID

       END "ASSGRP.ID"

  FROM T_GL_Voucher "VOUCHER"

  LEFT OUTER JOIN T_BD_Period "PERIOD"

    ON "VOUCHER".FPeriodID = "PERIOD".FID

 INNER JOIN T_GL_VoucherEntry "ENTRIES"

    ON "VOUCHER".FID = "ENTRIES".FBillID

 INNER JOIN T_BD_AccountView "ACCOUNT"

    ON "ENTRIES".FAccountID = "ACCOUNT".FID

  LEFT OUTER JOIN T_GL_VoucherAssistRecord "ASSISTRECORDS"

    ON "ENTRIES".FID = "ASSISTRECORDS".FEntryID

 WHERE "VOUCHER".FID IN

       (select id from x)

 ORDER BY "ID" ASC, "ENTRIES.SEQ" ASC, "ASSISTRECORDS.SEQ" ASC

---======执行计划

------------------------------------------------------------------------------------------------------

| Id  | Operation                         | Name                        | Rows  | Bytes | Cost (%CPU)|

------------------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT                  |                             |    24 | 11208 |   506   (1)|

|   1 |  TEMP TABLE TRANSFORMATION        |                             |       |       |            |

|   2 |   LOAD AS SELECT                  | SYS_TEMP_0FD9D6853_1AD5C99D |       |       |            |

|   3 |    HASH JOIN                      |                             |     1 |   415 |   458   (1)|

|   4 |     NESTED LOOPS                  |                             |       |       |            |

|   5 |      NESTED LOOPS                 |                             |   258 | 83850 |   390   (0)|

|   6 |       NESTED LOOPS                |                             |     6 |  1332 |     3   (0)|

|   7 |        TABLE ACCESS BY INDEX ROWID| T_BD_ACCOUNTVIEW            |     1 |   111 |     2   (0)|

|   8 |         INDEX UNIQUE SCAN         | PK_BD_ACCOUNTVIEW           |     1 |       |     1   (0)|

|   9 |        INDEX RANGE SCAN           | IX_BD_ACTCOMLNUM            |     6 |   666 |     1   (0)|

|  10 |       INDEX RANGE SCAN            | IX_GL_VCHAACCT              |   489 |       |     1   (0)|

|  11 |      TABLE ACCESS BY INDEX ROWID  | T_GL_VOUCHERENTRY           |    42 |  4326 |    65   (0)|

|  12 |     INDEX RANGE SCAN              | IX_GL_VCH_11                |  7536 |   662K|    68   (0)|

|  13 |   SORT ORDER BY                   |                             |    24 | 11208 |    48   (5)|

|  14 |    NESTED LOOPS OUTER             |                             |    24 | 11208 |    47   (3)|

|  15 |     NESTED LOOPS                  |                             |    17 |  6086 |    21   (5)|

|  16 |      NESTED LOOPS                 |                             |    17 |  5253 |    13   (8)|

|  17 |       NESTED LOOPS OUTER          |                             |     1 |   121 |     5  (20)|

|  18 |        NESTED LOOPS               |                             |     1 |    87 |     4  (25)|

|  19 |         VIEW                      | VW_NSO_1                    |     1 |    29 |     2   (0)|

|  20 |          HASH UNIQUE              |                             |     1 |    24 |            |

|  21 |           VIEW                    |                             |     1 |    24 |     2   (0)|

|  22 |            TABLE ACCESS FULL      | SYS_TEMP_0FD9D6853_1AD5C99D |     1 |    29 |     2   (0)|

|  23 |         INDEX RANGE SCAN          | IX_GL_VCH_FIDCMPNUM         |     1 |    58 |     1   (0)|

|  24 |        INDEX RANGE SCAN           | IX_PERIOD_ENC               |     1 |    34 |     1   (0)|

|  25 |       TABLE ACCESS BY INDEX ROWID | T_GL_VOUCHERENTRY           |    17 |  3196 |     8   (0)|

|  26 |        INDEX RANGE SCAN           | IX_GL_VCHENTRYFQ1           |    17 |       |     1   (0)|

|  27 |      TABLE ACCESS BY INDEX ROWID  | T_BD_ACCOUNTVIEW            |     1 |    49 |     1   (0)|

|  28 |       INDEX UNIQUE SCAN           | PK_BD_ACCOUNTVIEW           |     1 |       |     1   (0)|

|  29 |     TABLE ACCESS BY INDEX ROWID   | T_GL_VOUCHERASSISTRECORD    |     1 |   109 |     2   (0)|

|  30 |      INDEX RANGE SCAN             | IX_GL_VCHASSREC_11          |     2 |       |     1   (0)|

------------------------------------------------------------------------------------------------------

最后 1分钟全部查询出来,42956条数据

其实这个sql 没有 优化彻底,如果真的要认真对待,大概30秒左右就能跑完 不过难得搞了

有sql 要优化 加我qq 692162374 或者 加 群  220761024

想要跟我学优化的,请点击这里

最后我才知道 这个哥们 18k了 现在 我操。。。。他跟我学了ORACLE sql优化大概4个月了



再一次利用with as 优化SQL的更多相关文章

  1. 【转】利用 force index优化sql语句性能

    今天写了一个统计sql,在一个近亿条数据的表上执行,200s都查不出结果.SQL如下: select customer,count(1) c from upv_** where created bet ...

  2. 利用 force index优化sql语句性能

    [转自:https://blog.csdn.net/bruce128/article/details/46777567]并进行总结 今天写了一个统计sql,在一个近亿条数据的表上执行,200s都查不出 ...

  3. 利用查询提示优化SQL

    数据库环境:SQL SERVER 2005 我们来看一下SQL语句及对应的数据量 SELECT COUNT(*) FROM cinvout_02 a WHERE ( a.dept_id IN ( SE ...

  4. 利用ordered hints优化SQL

    SQL_ID  4g70n3k9bqc5v, child number 0 ------------------------------------- MERGE INTO YJBZH_GRXDFHZ ...

  5. 利用DBMS_SQLTUNE优化SQL

    DBMS_SQLTUNE优化SQL是在oracle10g才出来的新特性,使用它能很大程度上方便对sql的分析和优化.执行DBMS_SQLTUNE包进行sql优化需要有advisor的权限: stat& ...

  6. 【转】使用SQL Tuning Advisor STA优化SQL

    SQL优化器(SQL Tuning Advisor STA)是Oracle10g中推出的帮助DBA优化工具,它的特点是简单.智能,DBA值需要调用函数就可以给出一个性能很差的语句的优化结果.下面介绍一 ...

  7. sql语句优化SQL Server

    MS   SQL   Server查询优化方法查询速度慢的原因很多,常见如下几种 1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷)          2.I/O吞吐量小,形成了 ...

  8. mysql优化SQL语句的一般步骤及常用方法

    一.优化SQL语句的一般步骤 1. 通过show status命令了解各种SQL的执行频率 mysqladmin extended-status 或: show [session|global]sta ...

  9. 转载 50种方法优化SQL Server数据库查询

    原文地址 http://www.cnblogs.com/zhycyq/articles/2636748.html 50种方法优化SQL Server数据库查询 查询速度慢的原因很多,常见如下几种: 1 ...

随机推荐

  1. JavaScript:利用递归实现对象深拷贝

    先来普及一下深拷贝和浅拷贝的区别浅拷贝:就是简单的复制,用等号即可完成 let a = {a: 1} let b = a 这就完成了一个浅拷贝但是当修改对象b的时候,我们发现对象a的值也被改变了 b. ...

  2. saltstack+python批量修改服务器密码

    saltstack安装:略过 python脚本修改密码: # -*- coding utf-8 -*- import socket import re import os import sys imp ...

  3. Spring_总结

    spring配置Bean 配置形式 基于XML文件的方式 属性注入 构造注入 泛型依赖注入 基于注解的方式 配置方式 全类名(反射) 通过工厂方法 FactoryBean 字面值 <![CDAT ...

  4. parkingLot

    一个支付宝停车支付生活号前端页面 //index.html //自定义键盘 <!DOCTYPE html> <html> <head> <meta chars ...

  5. Python里的堆heapq

    实际上,Python没有独立的堆类型,而只有一个包含一些堆操作函数的模块.这个模块名为heapq(其中的q表示队列),默认为小顶堆.Python中没有大顶堆的实现. 常用的函数 函 数 描 述 hea ...

  6. 【JZOJ4878】【NOIP2016提高A组集训第10场11.8】时空传送

    题目描述 经过旷久的战争,ZMiG和707逐渐培养出了深厚的感♂情.他们逃到了另一块大陆上,决定远离世间的纷争,幸福地生活在一起.钟情707的neither_nor决心要把他们拆散,他要动用手中最大杀 ...

  7. 【Mysql的那些事】数据库之ORM操作

    1:ORM的基础操作(必会) <1> all(): 查询所有结果 <2> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象 <3> get(* ...

  8. hdu1536 sg打表

    标记数组用bool型防止超时.输入的f[ ]要排序. #include<stdio.h> #include<string.h> #include<algorithm> ...

  9. 洛谷1758 BZOJ1566 管道取珠题解

    题目链接 一道人类智慧的dp题 首先我们可以将∑ai^2转化为求取两次,两次一样的方案数 然后用f[i][j][k][l]表示第一个人在第一个串中取到i第二个串中取到j 第二个人在一个串中取到k第二个 ...

  10. UVa 10599【lis dp,记忆化搜索】

    UVa 10599 题意: 给出r*c的网格,其中有些格子里面有垃圾,机器人从左上角移动到右下角,只能向右或向下移动.问机器人能清扫最多多少个含有垃圾的格子,有多少中方案,输出其中一种方案的格子编号. ...