0

ランディング ページのいくつかのクエリに取り組んでいます。このページには、ユーザー向けのさまざまな検索オプションがあります。クエリは、ユーザーが何を選択して DB2 データベースに送信したかに応じて、さまざまな要素から構成されます。全体として、100 を超える固有のクエリがあります。パフォーマンスの低下に取り組んでいますが、少し時間がかかりすぎています。したがって、基本的な構造は次のとおりです。

SELECT ...
FROM
TABLE A
--A few joins and a few left joins--
WHERE A.FIELD1 IS NOT NULL
  AND A.FIELD2 IN (:parameter) --No more than two values in here
  AND (
        A.FIELD3 IN ('ONE', 'TWO')
    OR (A.FIELD3 IN ('THREE','FOUR') AND A.FIELD4 BETWEEN :x AND :y)
  )
  AND A.FIELD5 IN (uncorrelated subquery, potentially returns over 1k values, usually less)

FIELD2 と 3 が選択され、その他はフィルター処理のみされます。ジョインで FIELD5 を使用していますが、サブクエリによるフィルタリングとは関係ありません。問題は (X OR Y) 句から来ています。現在のクエリの実行には約 3 秒かかります。OR 句のいずれかの条件を削除すると、10 分の 1 未満の時間で実行されます。奇妙なことに、両方を削除すると約 3 秒戻りますが、データセットのサイズがそれほど増加しないように見えるため、あまり意味がありません。OR 句を使用した説明計画、または両方の条件を使用しない説明計画はほぼ同じですが、関連するテーブルで同じインデックスにヒットしているように見えるため、インデックスの問題ではないようです。どちらの場合も、大きなコストは最も外側の NLJOIN から来ています。OR 句から 1 つの条件を削除します (したがって、

サブクエリとユニオンを使用してこれを回避しようとしたり、その句のみを区別する 2 つのクエリ間で UNION ALL を使用したりしました (これは、このインスタンスを少し助けましたが、他のクエリを大幅に遅くしました)。実行時間。クエリが非常に膨大なため、完全な詳細を投稿することはできませんが、うまくいけば、これでアイデアを理解するのに十分です. OR 句がループのオプティマイザーをスローする場合があることを知っているので、問題のある OR 句を回避するか、オプティマイザーをより良い方向に微調整するかについての一般的なアドバイスは、この例に直接固有のものでなくても、非常に高く評価されると思います。

4

3 に答える 3

1

case代わりにステートメントを試すことができます。

それ以外の

AND ( A.FIELD3 IN ('ONE', 'TWO') 
 OR (A.FIELD3 IN ('THREE','FOUR') AND A.FIELD4 BETWEEN :x AND :y))

使用する

AND CASE WHEN A.FIELD3 IN ('ONE', 'TWO') THEN 1 
     WHEN A.FIELD3 IN ('THREE','FOUR') AND A.FIELD4 BETWEEN :x AND :y THEN 1 ELSE 0 END = 1
于 2013-04-03T18:09:18.527 に答える
0

極端に思えるかもしれませんが、2 つの高速バージョンを結合することもできます... 1 つに次の行があります

AND A.FIELD3 IN ('ONE', 'TWO') 

そして1つ

A.FIELD3 IN ('THREE','FOUR') AND A.FIELD4 BETWEEN :x AND :y)
于 2013-04-03T18:11:10.050 に答える