以下查询需要220秒。我想调整它。 查询中主要使用三个表。两个很大,一个相当小。
表中的计数:
INST --14851330 records
INST_S_INC --52234424 records
INVES -- 80000 records
查询:
SELECT
(
SELECT CODE
FROM CURRENCY CURR
WHERE CURR.CURRENCY_ID =
( SELECT CURRENCY_ID
FROM INST INSTR--14851330 records
WHERE INSTR.INVES_ID = INV.INVES_ID
UNION ALL
SELECT CURRENCY_ID
FROM INST_S_INC ISI--52234424 records
WHERE ISI.INVES_ID = INV.INVES_ID
)
)
FROM INVES INV -- 80000 records
WHERE TRUNC(CREATED_DATETIME) <SYSDATE
ORDER BY CREATED_DATETIME
;--220 secs
我试图重写下面的查询,但它现在需要418秒。还有其他任何调整方法吗?
SELECT
(
SELECT CODE
FROM CURRENCY CURR
WHERE CURR.CURRENCY_ID =ISI.currency_id
union all
SELECT CODE
FROM CURRENCY CURR
WHERE CURR.CURRENCY_ID =INSTR.currency_id
) code
FROM INVES INV
left outer join (
select INVES_ID,currency_id from INST
) INSTR
on INSTR.INVES_ID = INV.INVES_ID
left outer join (
select INVES_ID,currency_id from INST_S_INC
) ISI
on ISI.INVES_ID = INV.INVES_ID
WHERE TRUNC(CREATED_DATETIME) <SYSDATE
ORDER BY CREATED_DATETIME
;--418 secs
答案 0 :(得分:0)
您可以更改:
TRUNC(CREATED_DATETIME) < SYSDATE
要:
CREATED_DATETIME < TRUNC( SYSDATE ) + INTERVAL '1' DAY
这将允许您使用CREATED_DATETIME
上的任何索引(而不必在TRUNC(CREATED_DATETIME)
上使用基于函数的索引。)
很难解释您的要求,因为您没有描述您要实现的目标或表结构,但您也可以尝试使用EXISTS
并直接从CURRENCY
表中选择:
SELECT curr.CODE
FROM CURRENCY CURR
WHERE EXISTS (
SELECT CURRENCY_ID
FROM INST
INNER JOIN
INVES
ON ( INST.INVES_ID = INVES.INVES_ID )
WHERE INSRT.CURRENCY_ID = CURR.CURRENCY_ID
AND CREATED_DATETIME < TRUNC( SYSDATE ) + INTERVAL '1' DAY
)
OR EXISTS (
SELECT CURRENCY_ID
FROM INST_S_INC ISI
INNER JOIN
INVES
ON ( ISI.INVES_ID = INVES.INVES_ID )
WHERE ISI.CURRENCY_ID = CURR.CURRENCY_ID
AND CREATED_DATETIME < TRUNC( SYSDATE ) + INTERVAL '1' DAY
)
或者在UNION ALL
内使用EXISTS
。
答案 1 :(得分:0)
WHERE TRUNC(CREATED_DATETIME) <SYSDATE
这个过滤器有什么意义?假设您将来不创建基本上定义整个表扫描的记录。
在没有解释计划和数据量,倾斜等细节的情况下进行性能调整是一个杯子的游戏,但这是我的猜测:
SELECT curr,code
FROM INVES INV
left outer join INST
on INSTR.INVES_ID = INV.INVES_ID
left outer join INST_S_INCISI
on ISI.INVES_ID = INV.INVES_ID
left outer join CURRENCY CURR
on CURR.CURRENCY_ID = coalesce (ISI.currency_id, INST.currency_id)
ORDER BY inv.CREATED_DATETIME
;-