执行 SQL 案例表达式非常慢(查询优化)
Posted
技术标签:
【中文标题】执行 SQL 案例表达式非常慢(查询优化)【英文标题】:Very slow performing SQL case-expression (query optimization) 【发布时间】:2018-03-27 12:21:28 【问题描述】:我得到了这个小代码,实际上要长得多,但我创建了一些临时工作表来加速测试,而不是一直运行“with”。查询运行正常,考虑的行数,直到下面显示的部分。我已经制作了两个临时表,“disc_memberlist”和 billing_disc。我想比较两者,并添加一个列,说明用户是否存在于 billing_disc 中(在这种情况下是 Y 和 N)如果我指定了预先确定的协议 ID,则选择工作正常。但是,如果我将其删除,并希望它遍历所有行,它就会爬行。每 10 秒 200 行(我需要解析一百万行)
有什么建议可以让我以更好的性能实现这一目标吗?
SELECT
dm.user_id
,dm.agreement_id
,dm.cust_id
,dm.offer_id
,dm.offer_type
,dm.resource_spec_id
,dm.memberlist_subscriber_count
,CASE
WHEN dm.user_id in (SELECT user_id
FROM disc_memberlist dm
WHERE dm.user_id IN (SELECT bd.resource_id
FROM billing_disc bd ))
THEN
'Y'
ELSE
'N'
END AS Exists_in_billing
执行计划是
"PLAN_TABLE_OUTPUT"
"Plan hash value: 3054186447"
" "
"------------------------------------------------------------------------------------------------"
"| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |"
"------------------------------------------------------------------------------------------------"
"| 0 | SELECT STATEMENT | | 1727K| 87M| 21G (1)|232:59:10 |"
"|* 1 | HASH JOIN SEMI | | 1 | 18 | 12480 (1)| 00:00:01 |"
"|* 2 | TABLE ACCESS FULL| AGREEMENT_MEMBERLIST_KRPS | 1 | 9 | 3896 (1)| 00:00:01 |"
"|* 3 | TABLE ACCESS FULL| BILLING_DISC_KRPS | 30 | 270 | 8585 (1)| 00:00:01 |"
"| 4 | TABLE ACCESS FULL | AGREEMENT_MEMBERLIST_KRPS | 1727K| 87M| 3899 (1)| 00:00:01 |"
"------------------------------------------------------------------------------------------------"
" "
"Predicate Information (identified by operation id):"
"---------------------------------------------------"
" "
" 1 - access(""DM"".""USER_ID""=""BD"".""RESOURCE_ID"")"
" 2 - filter(""USER_ID""=:B1)"
" 3 - filter(""BD"".""RESOURCE_ID""=:B1)"
【问题讨论】:
可以分享一下执行计划吗? 【参考方案1】:您应该使用LEFT JOIN
而不是IN
。如果您在 disc_memberlist.user_id
和 billing_disc.resource_id
列上有正确的索引,它应该会提高性能,因为它不会在您的表中进行完整扫描。
SELECT
dm.user_id
,dm.agreement_id
,dm.cust_id
,dm.offer_id
,dm.offer_type
,dm.resource_spec_id
,dm.memberlist_subscriber_count
,NVL2(bd.resource_id, 'Y', 'N') AS Exists_in_billing
FROM disc_memberlist dm
LEFT JOIN billing_disc bd ON dm.user_id = bd.resource_id;
【讨论】:
【参考方案2】:我建议使用三个表创建一个临时表 (LEFT JOIN
)。不要忘记使用procedure analyse
索引和创建正确的变量。也可以尝试EXPLAIN
查询,它会给你更多关于如何提高性能的提示。
【讨论】:
以上是关于执行 SQL 案例表达式非常慢(查询优化)的主要内容,如果未能解决你的问题,请参考以下文章