我正在使用oraclepl/sql,我有一个存储过程来处理这个查询,它有点复杂,但是它完成了任务,问题是它需要大约35分钟,sql开发人员autotrace说,它正在做一个完整的扫描,即使表有它们的索引。
那么有什么方法可以改进这个查询吗?
select tipotrx, sum(saldo) as saldo,
count(*) as totaltrx from (
select max(ids) as IDTRX, max(monto) as monto, min(saldo) as saldo, max(aq_data) as aq_data, thekey, tipotrx
from (
select t.SID as ids, (TO_NUMBER(SUBSTR(P.P1, 18, 12))) as monto,
((TO_NUMBER(SUBSTR(P.P1, 18, 12)) * (TO_NUMBER(SUBSTR(t.acquirer_data, 13,2)) -
TO_NUMBER(SUBSTR(P.P4, 3,2))))) as saldo,
(TO_CHAR(t.trx_date, 'YYMMDD') || t.auth_code || t.trx_amount || (SELECT
functions.decrypt(t.card_number) FROM DUAL)) as thekey,
t.acquirer_data AS aq_data,
TO_NUMBER(SUBSTR(t.acquirer_data, 12, 1)) as tipotrx
from TBL_TRX t INNER JOIN TBL_POS P ON (t.SID = P.transaction)
WHERE (TO_NUMBER(SUBSTR(t.acquirer_data, 13,2)) >= TO_NUMBER(SUBSTR(P.P4, 3,2)))
AND trunc(t.INC_DATE) between (TO_DATE('20/06/2020', 'DD/MM/YYYY') - 35) AND TO_DATE('20/06/2020', 'DD/MM/YYYY')
) t
group by thekey, tipotrx order by max(ids) desc) j
group by tipotrx;
谢谢。
2条答案
按热度按时间zlwx9yxi1#
更改此项:
对此:
不需要构建基于函数的索引,您可以将 predicate 修改为可搜索的(能够使用索引)。而不是使用
TRUNC
要从列中减去,请在上限文字上加上一天减去一秒钟。代码比较混乱,但应该能够利用索引。但是,35天的数据量可能很大;日期索引可能不是很有用,您可能需要查看其他 predicate 。
7gcisfzg2#
大多数情况下,索引必须完全匹配where子句中的内容才能使用。当您的where子句显示
当where子句显示
操作where子句中的每一列,仅此一项就可能阻止使用任何普通索引。
但是,如果创建基于函数的索引,则可以创建一些与where子句中的内容匹配的新索引。这样,数据库至少有可能使用索引,而不是进行全表扫描。
当然,新索引会占用更多的空间,并增加自己的开销。继续用自动竞速看是否值得。
此外,更新表统计信息可能也不会有什么坏处。