秒杀SQL 之分页语句 count 优化

  今天碰到一SQL, 感觉典型的优化,  好久没有遇到怎么好的案例了, 简单记录之

  中午 和朋友们交流SQL, 感觉交流SQL属于比较难的了, 像在OLAP系统中报表里面常用的。突然 以女DBA发来一个SQL,  外话,这个女DBA  大有来头。  OCM级别, 公司

 更是牛逼!

  SELECT COUNT(*)
  FROM (SELECT  DISTINCT t1.ID,
                        t1.ITEM_ID,
                        t1.ITEM_DESCRIPTION,
                        t1.CATEGORY_NODE_ID,
                        t1.CATEGORY_NAME,
                        t1.CATEGORY_CODE,
                        t1.MIDCAT_NODE_ID,
                        t1.MIDCAT_NAME,
                        t1.MIDCAT_CODE,
                        t1.SUBCAT_NODE_ID,
                        t1.SUBCAT_NAME,
                        t1.SUBCAT_CODE,
                        t1.COMMODITY_NODE_ID,
                        t1.COMMODITY_NAME,
                        t1.COMMODITY_CODE,
                        t1.TAX_RATE,
                        t1.PRICE_TYPE,
                        t1.SUPPLIER_ID,
                        t1.SUPPLIER_NAME,
                        t1.MANU_ID,
                        t1.MANU_NAME,
                        t1.BUYER_ORG_ID,
                        t1.SUP_TYPE,
                        t1.PRICE_TERMS,
                        t1.CATALOG_TYPE,
                        PRICE_INFO.BPO_AMT_HEADER_ID,
                        PRICE_INFO.SOURCE_LINEID,
                        PRICE_INFO.BATCH_NUMBER,
                        PRICE_INFO.BPO_LINE_NUM,
                        PRICE_INFO.NO_TAX_PRICE,
                        PRICE_INFO.EXIST_TAX_PRICE,
                        PRICE_INFO.TRANS_EXP,
                        PRICE_INFO.INCI_EXP,
                        PRICE_INFO.TARIFFCOST,
                        PRICE_INFO.INSURANCECOST,
                        PRICE_INFO.TIERED_QTY,
                        PRICE_INFO.INPUTORDERID,
                        PRICE_INFO.OTHER_COST,
                        PRICE_INFO.PROC_MODE,
                        PRICE_INFO.SOURCE
          FROM PC_CA_PROC_DETAILS t1, PC_CA_PROC_PRICING_DETAILS PRICE_INFO
         WHERE (PRICE_INFO.CA_PROC_LINE_ID = t1.ID AND
               (PRICE_INFO.RECORD_STATUS = 'ACTIVE') AND
               (PRICE_INFO.VALID_FROM <= to_date('20170118 00:00:00','yyyymmdd hh24:mi:ss')) AND
               (PRICE_INFO.VALID_TO >= to_date('20170118 23:44:44','yyyymmdd hh24:mi:ss')) AND
               ((PRICE_INFO.NO_TAX_PRICE > 0) OR(PRICE_INFO.EXIST_TAX_PRICE > 0)))
           AND (t1.BUYER_ORG_ID IN ('ORG43', 'ORG00001'))
           AND (t1.STATUS = 'ACTIVE')
           AND (t1.MANU_NAME = '宝鸡住金石油钢管有限公司')) a

 是分页语句中的SQL, 简单看下, 大致知道大概。  执行计划:


-----------------------------------------------------------------------------------------------------------
| Id  | Operation                          | Name                       | Rows | Bytes  | Cost | Time     |
-----------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                     |                            |    1 |      4 | 1496 | 00:00:18 |
|   1 |   SORT   AGGREGATE                   |                            |    1 |      4 |      |          |
|   2 |    VIEW                              |                            |  207 |    828 | 1496 | 00:00:18 |
|   3 |     HASH   UNIQUE                    |                            |  207 | 204309 | 1496 | 00:00:18 |
|   4 |      NESTED LOOPS                    |                            |      |        |      |          |
|   5 |       NESTED LOOPS                   |                            |  207 | 204309 | 1495 | 00:00:18 |
| * 6 |        TABLE ACCESS   BY INDEX ROWID | PC_CA_PROC_DETAILS         |  207 | 161460 |  803 | 00:00:10 |
| * 7 |         INDEX   RANGE SCAN           | IND_PCPD_MANUNAME          | 2936 |        |   24 | 00:00:01 |
| * 8 |        INDEX   RANGE SCAN            | IDX_PCPPD_RIBC             |    1 |        |    3 | 00:00:01 |
| * 9 |       TABLE ACCESS   BY INDEX ROWID  | PC_CA_PROC_PRICING_DETAILS |    1 |    207 |    4 | 00:00:01 |
-----------------------------------------------------------------------------------------------------------




Predicate Information (identified by operation id):
------------------------------------------
* 6 - filter("T1"."STATUS"='ACTIVE' AND ("T1"."BUYER_ORG_ID"='ORG00001' OR "T1"."BUYER_ORG_ID"='ORG43'))
* 7 - access("T1"."MANU_NAME"='瀹濋浮浣忛噾鐭虫补閽㈢鏈夐檺鍏徃')
* 8 - access("PRICE_INFO"."CA_PROC_LINE_ID"="T1"."ID" AND "PRICE_INFO"."RECORD_STATUS"='ACTIVE')
* 9 - filter("PRICE_INFO"."VALID_TO">=TO_DATE(' 2017-01-18 23:44:44', 'syyyy-mm-dd hh24:mi:ss') AND "PRICE_INFO"."VALID_FROM"<=TO_DATE(' 2017-01-18 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND
  ("PRICE_INFO"."NO_TAX_PRICE">0 OR "PRICE_INFO"."EXIST_TAX_PRICE">0))


问她这个可以尝试 下走hash,   她说走hash 后结果出不了, 很慢很慢了,  她看了等待事件  ,

不亏是OCM, 很快知道这个是bug,   没办法  这个等待事件, 哥不懂,  于是继续优化,






开始看到SQL,以为hash 的, 后来看到数据量,  决定改为半连接, 哎 本来一眼就可以看出SQL怎么优化的, 不过还好殊途同归。   最后的 执行计划




最终原来SQL  40多S, 后来改后 0.5S ,    


至此,优化结束。  




猜你喜欢

转载自blog.csdn.net/daiqiulong2/article/details/54604430
今日推荐