我在下面有两个问题:
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;
它与示例案例几乎相同。
答案 0 :(得分:2)
“它与样本案例几乎相同。”实际上它并不像它。
在第一种情况下,您在左连接的左表上进行过滤。在第二个中,您将过滤查询的右侧(外部联接表)。
在这种情况下,OR 1=2
的存在很可能导致全表扫描解决它(再次,运行解释计划以查看此内容)。
但你的查询没有任何意义,因为你在外部加入RUN4_,然后在WHERE子句中对它进行过滤(而不是连接本身)。
run4_.NAME = 'RRP_XO-245'
你应该整理查询的逻辑。
答案 1 :(得分:1)
在这种情况下,原因是OR
。
在第一个查询中,引擎可能会在card_id上使用索引。它可能使用散列连接来连接两个表。
在第二个中,OR
的存在导致存在更多可能没有card_id = 23155的行的可能性。所以,索引是无用的:它应该扫描整个表。
此外,通常or
条件更难放入散列连接中,因此可能会强制执行NESTED LOOOPS JOIN。