【发布时间】:2014-09-15 00:59:00
【问题描述】:
我正在尝试提高针对 Oracle 10g 数据库的 SQL 查询的性能。我有以下两个查询:
查询 1
SELECT DISTINCT
WMS_EVENT_LOG.LOG_ID,
WMS_EVENT_LOG.EVENT_ARG4,
WMS_EVENT_LOG.EVENT_TYPE,
WMS_EVENT_LOG.EVENT_ARG1,
WMS_EVENT_LOG.EVENT_ARG3,
WMS_EVENT_LOG.PROD_ITEM_ID,
TRUNC(WMS_EVENT_LOG.LOG_DATE) AS LOG_DATE,
WMS_EVENT_LOG.PALLET_ID,
WMS_EVENT_LOG.LOG_USER,
WMS_EVENT_LOG.POSTED_TO_KCAT,
POSTEDWMSTRANS.POSTTRAN,
DECODE(POSTEDWMSTRANS.POSTTRAN, 'Y', POSTEDWMSTRANS.CMNT, WMS_EVENT_LOG.EVENT_ARG3) AS CMNT --cmnt = comment
FROM
VMR_WMSEVENTLOG WMS_EVENT_LOG,
VM_ADJUST_REASON ADJUST_REASON,
(
SELECT
INVENTORY.BOM_TYPE AS POSTTRAN,
INVENTORY.PROD_ITEM_ID,
INVENTORY.CMNT,
INVENTORY.WMSLINK
FROM
VR_BOM INVENTORY
WHERE
INVENTORY.BOM_TDATE >= TO_DATE(:report_start_date, 'YYYY/MM/DD') - 15 AND
INVENTORY.BOM_TDATE < TO_DATE(:report_end_date, 'YYYY/MM/DD') + 15 AND
INVENTORY.WMSLINK IS NOT NULL AND
INVENTORY.BOM_TYPE <> 'HLD'
) POSTEDWMSTRANS
WHERE
WMS_EVENT_LOG.LOG_DATE >= TO_DATE(:report_start_date, 'YYYY/MM/DD') AND
WMS_EVENT_LOG.LOG_DATE < TO_DATE(:report_end_date, 'YYYY/MM/DD') AND
WMS_EVENT_LOG.EVENT_TYPE = 31 AND
ADJUST_REASON.ADJUST_REASON_CODE NOT IN ('SPL') AND
ADJUST_REASON.ADJUST_REASON_CODE = WMS_EVENT_LOG.EVENT_ARG1 AND (
WMS_EVENT_LOG.EVENT_ARG1 <> 'MOV' AND
WMS_EVENT_LOG.EVENT_ARG2 = 'ADJUST'
) AND
WMS_EVENT_LOG.PROD_ITEM_ID = POSTEDWMSTRANS.PROD_ITEM_ID(+) AND
WMS_EVENT_LOG.EVENT_ARG4 = POSTEDWMSTRANS.WMSLINK(+)
查询 2
--VARIABLE report_start_date VARCHAR
--VARIABLE report_end_date VARCHAR
SELECT DISTINCT
WMS_EVENT_LOG.LOG_ID,
WMS_EVENT_LOG.EVENT_ARG4,
WMS_EVENT_LOG.EVENT_TYPE,
WMS_EVENT_LOG.EVENT_ARG1,
WMS_EVENT_LOG.EVENT_ARG3,
WMS_EVENT_LOG.PROD_ITEM_ID,
TRUNC(WMS_EVENT_LOG.LOG_DATE) AS LOG_DATE,
WMS_EVENT_LOG.PALLET_ID,
WMS_EVENT_LOG.LOG_USER,
WMS_EVENT_LOG.POSTED_TO_KCAT,
POSTEDWMSTRANS.POSTTRAN,
DECODE(POSTEDWMSTRANS.POSTTRAN, 'Y', POSTEDWMSTRANS.CMNT, WMS_EVENT_LOG.EVENT_ARG3) AS CMNT --cmnt = comment
FROM
VMR_WMSEVENTLOG WMS_EVENT_LOG,
VM_ADJUST_REASON ADJUST_REASON,
(
SELECT
INVENTORY.BOM_TYPE AS POSTTRAN,
INVENTORY.PROD_ITEM_ID,
INVENTORY.CMNT,
INVENTORY.WMSLINK
FROM
VR_BOM INVENTORY
WHERE
INVENTORY.BOM_TDATE >= TO_DATE(:report_start_date, 'YYYY/MM/DD') - 15 AND
INVENTORY.BOM_TDATE < TO_DATE(:report_end_date, 'YYYY/MM/DD') + 15 AND
INVENTORY.WMSLINK IS NOT NULL AND
INVENTORY.BOM_TYPE <> 'HLD'
) POSTEDWMSTRANS
WHERE
WMS_EVENT_LOG.LOG_DATE >= TO_DATE(:report_start_date, 'YYYY/MM/DD') AND
WMS_EVENT_LOG.LOG_DATE < TO_DATE(:report_end_date, 'YYYY/MM/DD') AND
WMS_EVENT_LOG.EVENT_TYPE = 31 AND
ADJUST_REASON.ADJUST_REASON_CODE NOT IN ('SPL') AND
ADJUST_REASON.ADJUST_REASON_CODE = WMS_EVENT_LOG.EVENT_ARG1 AND (
WMS_EVENT_LOG.EVENT_ARG1 <> 'MOV' AND
WMS_EVENT_LOG.EVENT_ARG2 = 'ADJUST'
) AND
WMS_EVENT_LOG.PROD_ITEM_ID = POSTEDWMSTRANS.PROD_ITEM_ID(+) AND
WMS_EVENT_LOG.EVENT_ARG4 = POSTEDWMSTRANS.WMSLINK(+)
如您所见,两个查询之间的唯一区别是顶部的 cmets。
由于某种原因,当我在 PL/SQL 开发人员中多次运行 query 2 时,它在一秒钟内完成。当我在同一环境中多次运行query 1 时,需要 15 秒才能完成。
我检查了返回的行,它们都返回了相同数量的具有相同数据的行。
为什么查询 2 会更快完成?
我相信这可能是 PL/SQL Developer 中的一个设置给了我错误的信息。
注意
所有这些最初都是为 8i 编写的,我正在为 10g 改进它。
【问题讨论】:
-
关闭 pl/sql dev,关闭你的数据库,重新启动,启动 plsqldev,运行一次查询 2 并测量执行需要多长时间
-
@Sebas 这是我试图加快速度的遗留代码,非常感谢您的建议。
-
猜猜重启数据库后会发生什么。如果问题消失了,你将永远不知道如何真正解决它,直到它再次发生并且你有机会。在 Oracle 工作的 20 年中,我几乎从来没有在稳定修补过的系统上重新启动 Oracle(注意我说的是虚拟的......是的,有一些案例)。您应该能够使用管理命令完成您需要的任何事情。那么重启有什么作用呢?刷新 SGA 和所有缓存并强制一切冷启动。在一切升温之前,您将失去“真实世界”的调优环境。
-
好吧,然后假设更快的时间是由于缓存。现在是时候优化您的查询了:)
-
如果您想进行优化,可以通过导航到 $ORACLE_HOME/rdbms/admin 目录来获取适合您的 oracle 数据库的 plan_table ddl 脚本。
标签: sql oracle plsqldeveloper sql-tuning