2

以下に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

(これは本当の場合ではありません。問題を示してください)

2番目のものがなぜそんなに遅いのか知りたいです(本当の場合はほぼ100倍遅い)。

さて、以下は私の場合のクエリ(オラクル)です:

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

「サンプルケースとほぼ同じです。」実際にはそのようなものではありません。

最初のケースでは、左結合の左テーブルでフィルタリングしていました。2 番目の例では、クエリの右側 (外部結合テーブル) でフィルター処理しています。

その場合に OR が存在する1=2と、ほとんどの場合、完全なテーブル スキャンで問題が解決されます (これを確認するには、Explain Plan を実行します)。

ただし、RUN4_ を外部結合しているが、(結合自体ではなく) WHERE 句でそれをフィルタリングするという点で、クエリは意味がありません。

run4_.NAME = 'RRP_XO-245'

クエリのロジックを整理する必要があります。

于 2013-01-17T10:16:00.337 に答える
1

この場合の原因はOR.

最初のクエリでは、エンジンは card_id のインデックスを使用する場合があります。おそらくハッシュ結合を使用して、2 つのテーブルを結合します。

2 番目の存在によりOR、card_id=23155 を持たない行がさらに存在する可能性が生じます。したがって、インデックスは役に立ちません。テーブル全体をスキャンする必要があります。

また、一般的なor条件ではハッシュ結合を入れるのが難しいため、NESTED LOOOPS JOIN を強制的に実行する必要がある場合があります。

于 2013-01-17T08:28:38.590 に答える