Sql 如何优化这个复杂的查询?
我正在运行一个包含很多条件的复杂查询。在大数据库上,查询需要2分钟以上。我正在使用Django进行我的项目。我可以优化这个查询吗?还是应该使用Django ORM查询?哪一个更快? LN_帐户表的行数超过300万行。任何建议和帮助都将不胜感激。非常感谢你Sql 如何优化这个复杂的查询?,sql,database,oracle,query-performance,sqlperformance,Sql,Database,Oracle,Query Performance,Sqlperformance,我正在运行一个包含很多条件的复杂查询。在大数据库上,查询需要2分钟以上。我正在使用Django进行我的项目。我可以优化这个查询吗?还是应该使用Django ORM查询?哪一个更快? LN_帐户表的行数超过300万行。任何建议和帮助都将不胜感激。非常感谢你 SELECT COUNT(*), SUM((select sum(acc.SALDO_EQUIVAL_OUT) from LN_ACCOUNT lna, ACCOUNTS acc where lna.LOAN_ID = L.LOAN_I
SELECT COUNT(*), SUM((select sum(acc.SALDO_EQUIVAL_OUT)
from LN_ACCOUNT lna, ACCOUNTS acc
where lna.LOAN_ID = L.LOAN_ID
and lna.LOAN_TYPE_ACCOUNT in ('1','4','5','8')
and lna.DATE_NEXT > '21.11.2020'
and lna.DATE_VALIDATE <= '20.11.2020'
and acc.CODE = lna.ACCOUNT_CODE
and (substr(lna.ACCOUNT_CODE, -20, 3) in ('163','915')
or (
select 'Y' from
V_REP_LN_BAL v
where v.BAL_ACC like substr(lna.ACCOUNT_CODE, -20, 3)||'%'
and ROWNUM = 1
) = 'Y'
)))/-100
FROM LN_CARD L
and
L.LOAN_ID IN (
select distinct (LOAN_ID) LID
from (
select (
select LOAN_ID
from LN_ACCOUNT s
where s.ACCOUNT_CODE = ac.CODE
and s.DATE_NEXT > '21.11.2020'
and s.DATE_VALIDATE <= '21.11.2020'
and rownum = 1) as LOAN_ID
from ACCOUNTS ac,
V_REP_LN_BAL vr
where vr.BAL_ACC = ac.CODE_COA
and vr.TYPE_BAL in (1, 2, 3, 4)
) lnIDS
where LOAN_ID is not null)
and (
select sum(abs(acc.SALDO_EQUIVAL_OUT))
from LN_ACCOUNT lna, ACCOUNTS acc
where lna.LOAN_ID = l.LOAN_ID
and lna.LOAN_TYPE_ACCOUNT in ('1','4','5','8')
and lna.DATE_NEXT > '21.11.2020'
and lna.DATE_VALIDATE <= '21.11.2020'
and acc.CODE = lna.ACCOUNT_CODE
and (substr(lna.ACCOUNT_CODE, -20, 3) in ('163','915')
or (
select 'Y' from
V_REP_LN_BAL v
where v.BAL_ACC like substr(lna.ACCOUNT_CODE, -20, 3)||'%'
and ROWNUM = 1
) = 'Y'
)
)
+ abs(
NVL((select sum(acc.SALDO_EQUIVAL_OUT)
from LN_ACCOUNT lna, ACCOUNTS acc
where lna.LOAN_ID = l.LOAN_ID
and lna.LOAN_TYPE_ACCOUNT = 3
and lna.DATE_NEXT > '21.11.2020'
and lna.DATE_VALIDATE <= '21.11.2020'
and acc.CODE = lna.ACCOUNT_CODE
and (substr(lna.ACCOUNT_CODE, -20, 3) in ('163','915')
or (select 'Y' from
V_REP_LN_BAL v
where v.BAL_ACC like substr(lna.ACCOUNT_CODE, -20, 3)||'%'
and ROWNUM = 1) = 'Y'
)),0) +
NVL((select sum(acc.SALDO_EQUIVAL_OUT)
from LN_ACCOUNT lna, ACCOUNTS acc
where lna.LOAN_ID = l.LOAN_ID
and lna.LOAN_TYPE_ACCOUNT = 7
and lna.DATE_NEXT > '21.11.2020'
and lna.DATE_VALIDATE <= '21.11.2020'
and acc.CODE = lna.ACCOUNT_CODE
and (substr(lna.ACCOUNT_CODE, -20, 3) in ('163','915')
or (select 'Y' from
V_REP_LN_BAL v
where v.BAL_ACC like substr(lna.ACCOUNT_CODE, -20, 3)||'%'
and ROWNUM = 1) = 'Y'
)),0) +
NVL((select sum(acc.SALDO_EQUIVAL_OUT)
from LN_ACCOUNT lna, ACCOUNTS acc
where lna.LOAN_ID = l.LOAN_ID
and lna.LOAN_TYPE_ACCOUNT = 79
and lna.DATE_NEXT > '21.11.2020'
and lna.DATE_VALIDATE <= '21.11.2020'
and acc.CODE = lna.ACCOUNT_CODE
and (substr(lna.ACCOUNT_CODE, -20, 3) in ('163','915')
or (select 'Y' from
V_REP_LN_BAL v
where v.BAL_ACC like substr(lna.ACCOUNT_CODE, -20, 3)||'%'
and ROWNUM = 1) = 'Y'
)),0)
)
+ abs(NVL((select sum(acc.SALDO_EQUIVAL_OUT)
from LN_ACCOUNT lna, ACCOUNTS acc
where lna.LOAN_ID = l.LOAN_ID
and lna.LOAN_TYPE_ACCOUNT = 46
and lna.DATE_NEXT > '21.11.2020'
and lna.DATE_VALIDATE <= '21.11.2020'
and acc.CODE = lna.ACCOUNT_CODE
and (substr(lna.ACCOUNT_CODE, -20, 3) in ('163','915')
or (select 'Y' from
V_REP_LN_BAL v
where v.BAL_ACC like substr(lna.ACCOUNT_CODE, -20, 3)||'%'
and ROWNUM = 1) = 'Y'
)),0))
+ abs(
NVL((select sum(acc.SALDO_EQUIVAL_OUT)
from LN_ACCOUNT lna, ACCOUNTS acc
where lna.LOAN_ID = l.LOAN_ID
and lna.LOAN_TYPE_ACCOUNT = 6
and lna.DATE_NEXT > '21.11.2020'
and lna.DATE_VALIDATE <= '21.11.2020'
and acc.CODE = lna.ACCOUNT_CODE
and (substr(lna.ACCOUNT_CODE, -20, 3) in ('163','915')
or (select 'Y' from
V_REP_LN_BAL v
where v.BAL_ACC like substr(lna.ACCOUNT_CODE, -20, 3)||'%'
and ROWNUM = 1) = 'Y'
)),0) +
NVL((select sum(acc.SALDO_EQUIVAL_OUT)
from LN_ACCOUNT lna, ACCOUNTS acc
where lna.LOAN_ID = l.LOAN_ID
and lna.LOAN_TYPE_ACCOUNT = 52
and lna.DATE_NEXT > '21.11.2020'
and lna.DATE_VALIDATE <= '21.11.2020'
and acc.CODE = lna.ACCOUNT_CODE
and (substr(lna.ACCOUNT_CODE, -20, 3) in ('163','915')
or (select 'Y' from
V_REP_LN_BAL v
where v.BAL_ACC like substr(lna.ACCOUNT_CODE, -20, 3)||'%'
and ROWNUM = 1) = 'Y'
)),0) +
NVL((select sum(acc.SALDO_EQUIVAL_OUT)
from LN_ACCOUNT lna, ACCOUNTS acc
where lna.LOAN_ID = l.LOAN_ID
and lna.LOAN_TYPE_ACCOUNT = 53
and lna.DATE_NEXT > '21.11.2020'
and lna.DATE_VALIDATE <= '21.11.2020'
and acc.CODE = lna.ACCOUNT_CODE
and (substr(lna.ACCOUNT_CODE, -20, 3) in ('163','915')
or (select 'Y' from
V_REP_LN_BAL v
where v.BAL_ACC like substr(lna.ACCOUNT_CODE, -20, 3)||'%'
and ROWNUM = 1) = 'Y'
)),0) +
NVL((select sum(acc.SALDO_EQUIVAL_OUT)
from LN_ACCOUNT lna, ACCOUNTS acc
where lna.LOAN_ID = l.LOAN_ID
and lna.LOAN_TYPE_ACCOUNT = 54
and lna.DATE_NEXT > '21.11.2020'
and lna.DATE_VALIDATE <= '21.11.2020'
and acc.CODE = lna.ACCOUNT_CODE
and (substr(lna.ACCOUNT_CODE, -20, 3) in ('163','915')
or (select 'Y' from
V_REP_LN_BAL v
where v.BAL_ACC like substr(lna.ACCOUNT_CODE, -20, 3)||'%'
and ROWNUM = 1) = 'Y'
)),0)
) <> 0;
您需要显示您的查询计划 为此,您可以使用SQL Developer并单击顶部工具栏快捷方式F10中的执行计划图标,也可以直接使用SQL PLus执行: 要解释一个计划:
explain plan
for
select * from table_name where ...;
要显示平面,请执行以下操作:
select * from table(dbms_xplan.display);
这里看一下完整的表格扫描行。这是一个由您完全读取的显示表。因此,如果一个表有超过3M行,这可能需要很长时间。为避免满表扫描,请在where子句中指定的列上创建索引。您正在对以下列执行多个嵌套子查询: +腹肌 NVLselect sumacc.SALDO_等效输出 来自LN_账户lna,账户acc 其中lna.LOAN\u ID=l.LOAN\u ID 和lna.LOAN_类型_账户=3 和lna.DATE_NEXT>“21.11.2020” 和lna.DATE_验证日期“2020-11-21”
和lna.DATE\u VALIDATE语法错误…您在SELECT子句和WHERE子句中使用了许多子查询。尝试将其转换为某种连接。我还能做些什么来减少执行时间?@Mika我不知道。为了得到更好的答案,您需要在问题中包含一个with:DDL语句,用于表;一些样本数据的DML语句;解释代码试图实现的目标;您对该样本数据的预期输出;以及当前查询的执行计划。。。如果没有这一点,我们将关注您的查询,并将挑选出性能方面的轻松胜利,但可能会错过一些基本的东西,即可能需要完全重写的完全不同的方法,但我们不知道这一点,因为我们没有您的表或数据,也不知道您的目标是什么。
CASE
WHEN LOAN_TYPE_ACCOUNT IN ( 3, 7, 79 ) THEN 'Group1'
WHEN LOAN_TYPE_ACCOUNT IN ( 46 ) THEN 'Group2'
WHEN LOAN_TYPE_ACCOUNT IN ( 6, 52, 53, 54 ) THEN 'Group3'
END