【问题标题】:DB2 Query running slowDB2 查询运行缓慢
【发布时间】:2021-11-04 06:15:12
【问题描述】:

我正在尝试加快运行速度非常慢的以下查询。这只是我使用的原始查询的一半,另一半是另一个查询的联合。 如果有人在以下查询中看到任何明显的危险信号,可以告诉我吗?

另一个痛苦的事情是,我无法在 index adivsor 中找到任何索引。

WITH
PREORDER AS (
  SELECT
    *
  FROM ORDERPAR
),
TCALLORDER AS (
  SELECT
    TPODR#,TPAREA,TPSEQ#
  FROM "ORDER"
    INNER JOIN OPTPLANP ON ORODR# = TPODR# EXCEPTION
    JOIN OPPLAN ON OPORD# = TPODR#
    AND TPSEQ# = OPTCSQ
),
FIRSTEQUIPRRN AS (
  SELECT
    OEORD# EQUIPORDER,MIN(RRN(A)) FIRSTROW
  FROM OPEQUIP A
  GROUP BY OEORD#
  ORDER BY 1),
FIRSTEQUIPROW AS (
  SELECT
    OEORD#,OETRLR EQUIPMENTNUMBER
  FROM FIRSTEQUIPRRN
    INNER JOIN OPEQUIP B ON EQUIPORDER = OEORD#
    AND FIRSTROW = RRN(B)
),
STOPGROUP AS(
  SELECT
    SOORD STOPORDER,
    COUNT(*) STOPSREMAIN,
    MIN(SOSTP#) NEXTSTOP,
    MAX(SOAPPR) APPTREQ,
    MAX(SOAPTM) APPTMADE
  FROM STOPOFF
    INNER JOIN "ORDER" ON ORODR# = SOORD
  WHERE SOARDT = 0
  GROUP BY SOORD
  ORDER BY 1
),
ORDERMILES AS (
SELECT
  MMORD#,MMTOTAL
FROM MMILES
WHERE MMORD# IN ( SELECT ORODR# FROM "ORDER" )
  AND MMRECTYPE = 'O'
  AND MMDSP# = '00'
),
NEGCOUNT AS (
  SELECT
    COUNT(*) NEGOTIATIONS,BNORD#
  FROM LMNEG
  GROUP BY BNORD#
)
SELECT
  A.ORODR# ORDER_NUMBER,
  ORCUST SHIPPER_ID,
  CUSTMS.CUNAME SHIPPER_NAME,
  CUSTMS.CUBAD1 SHIPPER_ADDRESS_1,
  CUSTMS.CUBAD2 SHIPPER_ADDRESS_2,
  CUSTMS.CUBCTY SHIPPER_CITY,
  CUSTMS.CUBST SHIPPER_ST,
  CUSTMS.CUBZIP SHIPPER_ZIP,
  CUSTMS.CUBZP2 SHIPPER_ZIP_EXT,
  ORLDAT LOAD_AT_ID,
  CUSTML.CUNAME LOAD_AT_NAME,
  CUSTML.CUBAD1 LOAD_AT_ADDRESS_1,
  CUSTML.CUBAD2 LOAD_AT_ADDRESS_2,
  CUSTML.CUBCTY LOAD_AT_CITY,
  CUSTML.CUBST LOAD_AT_ST,
  CUSTML.CUBZIP LOAD_AT_ZIP,
  CUSTML.CUBZP2 LOAD_AT_ZIP_EXT,
  MCCL.C#DECLATD LOAD_AT_LATITUDE,
  MCCL.C#DECLOND LOAD_AT_LONGITUDE,
  CASE WHEN ORPDAT <> 0
    AND ORPTIM = '' THEN CVTDATETIM(CHAR(ORPDAT),'0000',CMCPUZ) WHEN ORPDAT <> 0 THEN CVTDATETIM(CHAR(ORPDAT),ORPTIM,CMCPUZ) WHEN ORPDAT = 0 THEN '0000-00-00T00:00:00-00:00' END AS EARLY_PU_DATE_TIME,
  CASE WHEN ORAPDT <> 0
    AND ORAPTM = '' THEN CVTDATETIM(CHAR(ORAPDT),'0000',CMCPUZ) WHEN ORAPDT <> 0 THEN CVTDATETIM(CHAR(ORAPDT),ORAPTM,CMCPUZ) WHEN ORAPDT = 0 THEN '0000-00-00T00:00:00-00:00' END AS LATE_PU_DATE_TIME,
  CASE WHEN ORDDAT <> 0
    AND ORDTIM = '' THEN CVTDATETIM(CHAR(ORDDAT),'0000',CMCPUZ) WHEN ORDDAT <> 0 THEN CVTDATETIM(CHAR(ORDDAT),ORDTIM,CMCPUZ) WHEN ORDDAT = 0 THEN '0000-00-00T00:00:00-00:00' END AS EARLY_DELV_DATE_TIME,
  ORESTR EST_REVENUE,
  A.ORDV# ORDER_DIV,
  ORCONS CONSIGNEE_ID,
  CUSTMC.CUNAME CONSIGNEE_NAME,
  CUSTMC.CUBAD1 CONSIGNEE_ADDRESS_1,
  CUSTMC.CUBAD2 CONSIGNEE_ADDRESS_2,
  CUSTMC.CUBCTY CONSIGNEE_CITY,
  CUSTMC.CUBST CONSIGNEE_ST,
  CUSTMC.CUBZIP CONSIGNEE_ZIP,
  CUSTMC.CUBZP2 CONSIGNEE_ZIP_EXT,
  MCCC.C#DECLATD CONSIGNEE_LATITUDE,
  MCCC.C#DECLOND CONSIGNEE_LONGITUDE,
  OREQTY TRAILER_TYPE,
  ORSPEC ORDER_MESSAGE,
  A.ORSTP# ADDITIONAL_STOPS,
  ORCOMC CMDTY_CODE,
  ORCOMD CMDTY_DESCRIPTION,
  (COALESCE(MMTOTAL,0)) ORDER_MILES,
  ORWGT ORDER_WGT,
  OROCTY ORIGIN_CITY_CODE,
  CITYOR.CINAME ORIGIN_CITY,
  OROST ORIGIN_ST,
  ORDCTY DEST_CITY_CODE,
  CITYDEST.CINAME DEST_CITY_NAME,
  ORDST DEST_ST,
  ORARA PICK_UP_AREA,
  ORPDRV PLAN_INFO,
  ORLD# NUMBER_LDS,
  OR#DSP NUMBER_DISP,
  CASE WHEN ORSHDT <> 0
    AND ORSHTM = '' THEN CVTDATETIM(CHAR(ORSHDT),'0000',CMCPUZ) WHEN ORSHDT <> 0 THEN CVTDATETIM(CHAR(ORSHDT),ORSHTM,CMCPUZ) WHEN ORSHDT = 0 THEN '0000-00-00T00:00:00-00:00' END AS SHIP_DATE_TIME,
  ORNWPK NEW_PICKUP_AREA,
  (COALESCE(EQUIPMENTNUMBER,' ')) EQUIPMENT_NUMBER,
  (COALESCE(APPTREQ,'N')) APPT_REQ,
  (COALESCE(APPTMADE,'N')) APPT_MADE,
  (COALESCE(TPSEQ#,' ')) PRE_T_SEQ,
  (COALESCE(TPAREA,' ')) PRE_T_AREA,
  ORDSP# LOAD_DISPATCHED,
  CASE WHEN APPTREQ = ' '
  AND APPTMADE = ' ' THEN APPTMADE WHEN APPTREQ = 'N'
  AND APPTMADE = 'Y' THEN APPTMADE WHEN APPTREQ = 'Y'
  AND APPTMADE = 'Y' THEN 'Y' WHEN APPTREQ = 'N'
  AND APPTMADE = 'N' THEN APPTREQ WHEN APPTREQ = ' ' OR APPTMADE = ' ' THEN 'N' ELSE 'N' END AVAPPTREQ,
  ORSTAT,
  ORPDAT,
  CUSTMS.CUSVRP CUST_SERV_REP,
  NEGOTIATIONS
FROM SUBSIDIARY,"ORDER" A
  LEFT OUTER JOIN CUSTMAST CUSTMS ON ORCUST = CUSTMS.CUCODE
  LEFT OUTER JOIN CUSTMAST CUSTML ON ORLDAT = CUSTML.CUCODE
  LEFT OUTER JOIN CUSTMAST CUSTMC ON ORCONS = CUSTMC.CUCODE
  LEFT OUTER JOIN MCCSTLLP MCCS ON ORCUST = MCCS.C#CODE
  LEFT OUTER JOIN MCCSTLLP MCCL ON ORLDAT = MCCL.C#CODE
  LEFT OUTER JOIN MCCSTLLP MCCC ON ORCONS = MCCC.C#CODE
  LEFT OUTER JOIN CITIES CITYOR ON OROST = CITYOR.CIST AND OROCTY = CITYOR.CICTY
  LEFT OUTER JOIN CITIES CITYDEST ON ORDST = CITYDEST.CIST AND ORDCTY = CITYDEST.CICTY
  LEFT OUTER JOIN MMILES ON MMORD# = A.ORODR# AND MMRECTYPE = 'O' AND MMDSP# = '00'
  LEFT OUTER JOIN FIRSTEQUIPROW ON A.ORODR# = OEORD#
  LEFT OUTER JOIN STOPGROUP ON A.ORODR# = STOPORDER
  EXCEPTION JOIN OPPLAN ON OPORD# = A.ORODR#
  LEFT OUTER JOIN TCALLORDER ON TPODR# = A.ORODR#
  LEFT OUTER JOIN NEGCOUNT ON BNORD# = A.ORODR#
WHERE ( ORSTAT <> 'C' )
    

【问题讨论】:

标签: db2 ibm-midrange db2-400


【解决方案1】:

使用 IBM Access Client Solution (ACS) 的运行 SQL 脚本组件中的 Visual Explain (VE) 功能将向您显示查询花费时间的位置以及任何建议的索引。

话虽如此,使用 RRN() 通常是一个坏主意,而且您在这里使用它的方式非常可疑。

使用公用表表达式 (with MyCTE ...) 的另一个好处是,您可以通过添加 select * from lastCte; 来检查结果。

所以在你的情况下,

 WITH PREORDER AS
 (
 SELECT *
 FROM
 ORDERPAR
 )
 , TCALLORDER AS
 (
 SELECT
 TPODR#
 , TPAREA
 , TPSEQ#
 FROM
 "ORDER"
 INNER JOIN
 OPTPLANP
 ON
 ORODR# = TPODR#
 EXCEPTION JOIN
 OPPLAN
 ON
 OPORD# = TPODR#
 AND TPSEQ# = OPTCSQ
 )
 select * from tcallorder;

随着您继续沿着 CTE 向下走,您可以看到 VE 计划如何变化。

【讨论】:

    【解决方案2】:

    您必须构建查询结构,以便有机会理解并排除故障。

    运行strdbg 命令。然后从STRSQL 提示符运行查询。您应该会在作业日志中看到“建议的访问路径”消息。

    并连续运行 with 查询。第一个单独查询。然后是查询 1 到 2。然后是 1 到 3。要点是您正在运行它们以查看瓶颈在哪里。

    WITH PREORDER AS
     ( SELECT *  FROM ORDERPAR    ), 
    TCALLORDER AS
    ( SELECT  TPODR#, TPAREA, TPSEQ#
      FROM    "ORDER"
      INNER JOIN  OPTPLANP
      ON      ORODR# = TPODR#
      EXCEPTION JOIN OPPLAN
      ON     OPORD# = TPODR# AND TPSEQ# = OPTCSQ
    ),
    FIRSTEQUIPRRN AS
    ( SELECT OEORD# EQUIPORDER, MIN(RRN(A)) FIRSTROW
      FROM   OPEQUIP A
      GROUP BY OEORD#
      ORDER BY 1
    ),
    FIRSTEQUIPROW AS
    ( SELECT OEORD#, OETRLR EQUIPMENTNUMBER
      FROM   FIRSTEQUIPRRN
      INNER JOIN OPEQUIP B
      ON    EQUIPORDER = OEORD# AND FIRSTROW = RRN(B)
    ),
    STOPGROUP AS
    ( SELECT  SOORD STOPORDER, COUNT(*) STOPSREMAIN, MIN(SOSTP#) NEXTSTOP, MAX(SOAPPR) APPTREQ,
              MAX(SOAPTM) APPTMADE
      FROM    STOPOFF
      INNER JOIN "ORDER"
      ON      ORODR# = SOORD
      WHERE   SOARDT = 0
      GROUP BY SOORD
      ORDER BY 1
    ),
    ORDERMILES AS
    ( SELECT  MMORD#, MMTOTAL
      FROM    MMILES
      WHERE   MMORD# IN ( SELECT ORODR#
                          FROM   "ORDER" )
              AND MMRECTYPE = 'O' AND MMDSP# = '00'
    ),
    NEGCOUNT AS
    ( SELECT  COUNT(*) NEGOTIATIONS, BNORD#
      FROM    LMNEG
      GROUP BY BNORD#
    )
    
    SELECT   A.ORODR# ORDER_NUMBER, ORCUST SHIPPER_ID, CUSTMS.CUNAME SHIPPER_NAME,
             CUSTMS.CUBAD1 SHIPPER_ADDRESS_1, CUSTMS.CUBAD2 SHIPPER_ADDRESS_2, CUSTMS.CUBCTY SHIPPER_CITY, 
             CUSTMS.CUBST SHIPPER_ST, CUSTMS.CUBZIP SHIPPER_ZIP, CUSTMS.CUBZP2 SHIPPER_ZIP_EXT,
             ORLDAT LOAD_AT_ID, CUSTML.CUNAME LOAD_AT_NAME, CUSTML.CUBAD1 LOAD_AT_ADDRESS_1, CUSTML.CUBAD2 LOAD_AT_ADDRESS_2,
             CUSTML.CUBCTY LOAD_AT_CITY, CUSTML.CUBST LOAD_AT_ST, CUSTML.CUBZIP LOAD_AT_ZIP,
             CUSTML.CUBZP2 LOAD_AT_ZIP_EXT, MCCL.C#DECLATD LOAD_AT_LATITUDE, MCCL.C#DECLOND LOAD_AT_LONGITUDE,
             CASE WHEN ORPDAT <> 0 AND ORPTIM = ''
                  THEN CVTDATETIM(CHAR(ORPDAT),'0000', CMCPUZ)
                  WHEN ORPDAT <> 0
                  THEN CVTDATETIM(CHAR(ORPDAT),ORPTIM, CMCPUZ)
                  WHEN ORPDAT = 0
                  THEN '0000-00-00T00:00:00-00:00' END AS EARLY_PU_DATE_TIME,
             CASE WHEN ORAPDT <> 0 AND ORAPTM = ''
                  THEN CVTDATETIM(CHAR(ORAPDT),'0000', CMCPUZ)
                  WHEN ORAPDT <> 0
                  THEN CVTDATETIM(CHAR(ORAPDT),ORAPTM, CMCPUZ)
                  WHEN ORAPDT = 0
                  THEN '0000-00-00T00:00:00-00:00' END AS LATE_PU_DATE_TIME,
             CASE WHEN ORDDAT <> 0 AND ORDTIM = ''
                  THEN CVTDATETIM(CHAR(ORDDAT),'0000',CMCPUZ)
                  WHEN ORDDAT <> 0
                  THEN CVTDATETIM(CHAR(ORDDAT),ORDTIM, CMCPUZ)
                  WHEN ORDDAT = 0
                  THEN '0000-00-00T00:00:00-00:00' END AS EARLY_DELV_DATE_TIME,
              ORESTR EST_REVENUE, A.ORDV# ORDER_DIV, ORCONS CONSIGNEE_ID, CUSTMC.CUNAME CONSIGNEE_NAME,
              CUSTMC.CUBAD1 CONSIGNEE_ADDRESS_1, CUSTMC.CUBAD2 CONSIGNEE_ADDRESS_2, CUSTMC.CUBCTY CONSIGNEE_CITY,
              CUSTMC.CUBST CONSIGNEE_ST, CUSTMC.CUBZIP CONSIGNEE_ZIP, CUSTMC.CUBZP2 CONSIGNEE_ZIP_EXT,
              MCCC.C#DECLATD CONSIGNEE_LATITUDE, MCCC.C#DECLOND CONSIGNEE_LONGITUDE, OREQTY TRAILER_TYPE,
              ORSPEC ORDER_MESSAGE, A.ORSTP# ADDITIONAL_STOPS, ORCOMC CMDTY_CODE, ORCOMD CMDTY_DESCRIPTION,
              (COALESCE(MMTOTAL, 0)) ORDER_MILES, ORWGT ORDER_WGT, OROCTY ORIGIN_CITY_CODE,
              CITYOR.CINAME ORIGIN_CITY, OROST ORIGIN_ST, ORDCTY DEST_CITY_CODE, CITYDEST.CINAME DEST_CITY_NAME,
              ORDST DEST_ST, ORARA PICK_UP_AREA, ORPDRV PLAN_INFO, ORLD# NUMBER_LDS, OR#DSP NUMBER_DISP,
              CASE WHEN ORSHDT <> 0 AND ORSHTM = ''
                   THEN CVTDATETIM(CHAR(ORSHDT),'0000',CMCPUZ)
              WHEN ORSHDT <> 0
              THEN CVTDATETIM(CHAR(ORSHDT),ORSHTM,CMCPUZ)
              WHEN ORSHDT = 0
              THEN '0000-00-00T00:00:00-00:00'
              END AS SHIP_DATE_TIME,
              ORNWPK NEW_PICKUP_AREA, (COALESCE(EQUIPMENTNUMBER, ' ')) EQUIPMENT_NUMBER,
              (COALESCE(APPTREQ, 'N')) APPT_REQ, (COALESCE(APPTMADE, 'N')) APPT_MADE,
              (COALESCE(TPSEQ#, ' ')) PRE_T_SEQ, (COALESCE(TPAREA, ' ')) PRE_T_AREA, ORDSP# LOAD_DISPATCHED,
              CASE WHEN APPTREQ = ' ' AND APPTMADE = ' '
                   THEN APPTMADE
                   WHEN APPTREQ = 'N' AND APPTMADE = 'Y'
                   THEN APPTMADE
                   WHEN APPTREQ = 'Y' AND APPTMADE = 'Y'
                   THEN 'Y'
                   WHEN APPTREQ = 'N' AND APPTMADE = 'N'
                   THEN APPTREQ
                   WHEN APPTREQ = ' '  OR APPTMADE = ' '
                   THEN 'N'
                   ELSE 'N' END AVAPPTREQ,
             ORSTAT, ORPDAT, CUSTMS.CUSVRP CUST_SERV_REP, NEGOTIATIONS
    FROM     SUBSIDIARY, "ORDER" A
    LEFT OUTER JOIN  CUSTMAST CUSTMS
    ON       ORCUST = CUSTMS.CUCODE
    LEFT OUTER JOIN CUSTMAST CUSTML
    ON       ORLDAT = CUSTML.CUCODE
    LEFT OUTER JOIN CUSTMAST CUSTMC
    ON       ORCONS = CUSTMC.CUCODE
    LEFT OUTER JOIN MCCSTLLP MCCS
    ON       ORCUST = MCCS.C#CODE
    LEFT OUTER JOIN MCCSTLLP MCCL
    ON       ORLDAT = MCCL.C#CODE
    LEFT OUTER JOIN MCCSTLLP MCCC
    ON       ORCONS = MCCC.C#CODE
    LEFT OUTER JOIN CITIES CITYOR
    ON       OROST = CITYOR.CIST AND OROCTY = CITYOR.CICTY
    LEFT OUTER JOIN CITIES CITYDEST
    ON       ORDST = CITYDEST.CIST AND ORDCTY = CITYDEST.CICTY
    LEFT OUTER JOIN MMILES
    ON       MMORD# = A.ORODR# AND MMRECTYPE = 'O' AND MMDSP# = '00'
    LEFT OUTER JOIN FIRSTEQUIPROW
    ON       A.ORODR# = OEORD#
    LEFT OUTER JOIN STOPGROUP
    ON       A.ORODR# = STOPORDER
    EXCEPTION JOIN OPPLAN
    ON       OPORD# = A.ORODR#
    LEFT OUTER JOIN TCALLORDER
    ON       TPODR# = A.ORODR#
    LEFT OUTER JOIN NEGCOUNT
    ON BNORD# = A.ORODR#
    WHERE    ( ORSTAT <> 'C' )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-24
      • 2019-04-15
      • 2011-04-27
      • 1970-01-01
      相关资源
      最近更新 更多