2

我有以下两个查询:

SELECT cl.`cl_boolean`, l.`l_name`
FROM `card_legality` cl
LEFT JOIN `legality` l ON l.`legality_id` = cl.`legality_id`
WHERE cl.`card_id` = 23155


SELECT cl.`cl_boolean`, l.`l_name`
FROM `card_legality` cl
LEFT JOIN `legality` l ON l.`legality_id` = cl.`legality_id`
WHERE cl.`card_id` = 23155 or 1 = 2

(这不是真实情况,只是显示问题)

我想知道为什么第二个这么慢(在真实情况下几乎慢了 100 倍)。

好的,下面是我的查询(oracle):

select *
from LA_TESTCASE this_ 
left outer join LA_RULE   rule1_    on this_.ROOTCAUSE_RULE_ID = rule1_.ID 
left outer join LA_TEST   test2_    on this_.TEST_ID = test2_.ID 
left outer join LA_SUITE  suite3_   on test2_.SUITE_ID = suite3_.ID 
left outer join LA_RUN    run4_     on suite3_.RUN_ID = run4_.ID
where (run4_.NAME = 'RRP_XO-245'/* or 1 = 2*/)
order by this_.ID desc;

它与示例案例几乎相同。

4

2 回答 2

2

“和样例差不多。” 实际上它一点也不像。

在第一种情况下,您正在过滤左连接的左表。在第二个中,您在查询的右侧(外部连接表)进行过滤。

在这种情况下,OR 的存在1=2很可能会导致全表扫描来解决它(同样,运行解释计划以查看这一点)。

但是您的查询没有任何意义,因为您是外部加入 RUN4_ ,然后在 WHERE 子句中对其进行过滤(而不是加入本身)。

run4_.NAME = 'RRP_XO-245'

你应该整理一下查询的逻辑。

于 2013-01-17T10:16:00.337 回答
1

在这种情况下,原因是OR

在第一个查询中,引擎可能会使用 card_id 上的索引。它可能使用散列连接来连接两个表。

在第二个存在OR导致可能存在更多可能没有card_id = 23155的行的可能性。所以,索引是没用的:它应该扫描整个表。

此外,在一般or情况下更难放入哈希连接,因此可能会被迫进行嵌套循环连接。

于 2013-01-17T08:28:38.590 回答