我们可以调整下面的oracle sql查询吗?此查询需要花费大量时间从数据库中获取行。
SELECT T.ACCUMULATORS_INFO ACCU_INFO, T.SUBSCR_NO service_internal_id,
T.SUBSCR_NO_RESETS service_internal_id_resets, T.*,T.MTR_TYPE_ID MTR_TYPE,
T.ACCOUNT_NO account_internal_id, T.MTR_SUB_TYPE_ID MTR_SUB_TYPE,
T.FILE_ID EXTRACT_FILE_ID, T.UNIT_TYPE_ID unit_type, RCV2.ISO_CODE PREV_SUBSCRIBER_CURRENCY,
T.MTR_SOURCE_ID MTR_SOURCE, RCV1.ISO_CODE SUBSCRIBER_CURRENCY
FROM MTR T
LEFT OUTER JOIN RATE_CURRENCY_REF RCV1 ON (T.CURRENCY_CODE = RCV1.CURRENCY_CODE)
LEFT OUTER JOIN RATE_CURRENCY_REF RCV2 ON (T.PREV_CURRENCY_CODE = RCV2.CURRENCY_CODE)
WHERE (T.CURRENCY_CODE IS NULL OR RCV1.service_version_id = ?) AND
(T.PREV_CURRENCY_CODE IS NULL OR RCV2.service_version_id = ?) AND
T.mod_date BETWEEN ? AND ? AND T.subscr_no = ? AND
T.subscr_no_resets = ?
ORDER BY T.mod_date DESC
此致 钱德拉
答案 0 :(得分:0)
在不知道模型和数据的情况下优化查询总是很困难,但我会尝试这样做。
你至少应该有一个索引
rate_currency_ref (currency_code, service_version_id )
也许一个在上
mtr (mod_date, subscr_no, subscr_no_resets)
。
我还会调整查询以获得LEFT JOIN
中的附加条件,以提高可读性(并且可能更好的优化)。
SELECT T.ACCUMULATORS_INFO ACCU_INFO, T.SUBSCR_NO service_internal_id,
T.SUBSCR_NO_RESETS service_internal_id_resets, T.*,T.MTR_TYPE_ID MTR_TYPE,
T.ACCOUNT_NO account_internal_id, T.MTR_SUB_TYPE_ID MTR_SUB_TYPE,
T.FILE_ID EXTRACT_FILE_ID, T.UNIT_TYPE_ID unit_type, RCV2.ISO_CODE PREV_SUBSCRIBER_CURRENCY,
T.MTR_SOURCE_ID MTR_SOURCE, RCV1.ISO_CODE SUBSCRIBER_CURRENCY
FROM MTR T
LEFT OUTER JOIN RATE_CURRENCY_REF RCV1
ON (T.CURRENCY_CODE = RCV1.CURRENCY_CODE AND RCV1.service_version_id = ?)
LEFT OUTER JOIN RATE_CURRENCY_REF RCV2
ON (T.PREV_CURRENCY_CODE = RCV2.CURRENCY_CODE AND RCV2.service_version_id = ?)
WHERE
T.mod_date BETWEEN ? AND ? AND T.subscr_no = ? AND
T.subscr_no_resets = ?
ORDER BY T.mod_date DESC
答案 1 :(得分:0)
SQl在...(CURRENCY_CODE IS NULL OR service_version_id_RCV1 = ?)
无论如何,假设SQL在功能上是正确的并且尽管“Peter”建议的索引表现不佳,我会调整并重写SQL(使用子查询)以允许优化器选择更好的计划: -
SELECT tmp.*
FROM
(SELECT T.ACCUMULATORS_INFO ACCU_INFO,
T.SUBSCR_NO service_internal_id,
T.SUBSCR_NO_RESETS service_internal_id_resets,
T.*,
T.MTR_TYPE_ID MTR_TYPE,
T.ACCOUNT_NO account_internal_id,
T.MTR_SUB_TYPE_ID MTR_SUB_TYPE,
T.FILE_ID EXTRACT_FILE_ID,
T.UNIT_TYPE_ID unit_type,
RCV2.ISO_CODE PREV_SUBSCRIBER_CURRENCY,
RCV2.service_version_id_RCV2,
T.MTR_SOURCE_ID MTR_SOURCE,
RCV1.ISO_CODE SUBSCRIBER_CURRENCY,
RCV1.service_version_id_RCV1
FROM MTR T
LEFT OUTER JOIN RATE_CURRENCY_REF RCV1
ON (T.CURRENCY_CODE = RCV1.CURRENCY_CODE)
LEFT OUTER JOIN RATE_CURRENCY_REF RCV2
ON (T.PREV_CURRENCY_CODE = RCV2.CURRENCY_CODE)
WHERE T.mod_date BETWEEN ? AND ?
AND T.subscr_no = ?
AND T.subscr_no_resets = ?
) tmp
WHERE (CURRENCY_CODE IS NULL OR service_version_id_RCV1 = ?)
AND (PREV_CURRENCY_CODE IS NULL OR service_version_id_RCV2 = ?)
ORDER BY mod_date DESC
我建议在MTR,RATE_CURRENCY_REF上保留以下索引: