【发布时间】:2016-05-27 19:50:03
【问题描述】:
这是我的查询,
SELECT si.* FROM
FROM SHIPMENT_ITEMS si
WHERE ID IN ( SELECT ID FROM id_map WHERE code = 'A' )
AND LAST_UPDATED BETWEEN TO_DATE('20150102','YYYYMMDD') - 1 AND TO_DATE('20150103','YYYYMMDD')
SHIPMENT_ITEMS 是一个非常大的表(10.1TB),id_map 是一个非常小的表(12 行和 3 列)。此查询经过 HASH_JOIN_RIGHT_SEMI 并且需要很长时间。SHIPMENT_ITEMS 在 ID 列上进行分区。
如果我删除带有硬编码值的子查询,它的性能会好很多
SELECT si.* FROM
FROM SHIPMENT_ITEMS si
WHERE ID IN (1,2,3 )
AND LAST_UPDATED BETWEEN TO_DATE('20150102','YYYYMMDD') - 1 AND TO_DATE('20150103','YYYYMMDD')
我无法删除子查询,因为它会导致硬编码。
鉴于 id_map 是一个非常小的表,我希望这两个查询的执行非常相似。为什么第一个需要更长的时间。
我实际上是想了解为什么它的表现如此糟糕。
我预计动态分区修剪会在这里发生,但我无法找到它为什么没有发生的原因
https://docs.oracle.com/cd/E11882_01/server.112/e25523/part_avail.htm#BABHDCJG
【问题讨论】:
-
IN 的性能非常低,您尝试加入表格吗?还是使用存在?
-
这将有助于为两个查询添加解释计划以查看它们之间的区别。运行
explain plan for select ...;,然后运行select * from table(dbms_xplan.display);,然后在此处发布整个 输出。此外,这些是正在运行的真正查询吗?似乎他们会返回数百万行,这通常没有意义。您是在比较从某个 IDE 返回所有行还是仅返回前 N 行的时间?
标签: sql oracle performance oracle11g database-performance