1

次のようなクエリ(Oracle DBで実行)があります。

SELECT 
Column1,Column2,Column3 FROM MyDatabase.MyTableName 
WHERE 
(DELETED = 0) 
AND (DATESEEN > TO_DATE ('20/03/2013 12:00:00', 'DD/MM/YYYY HH24:MI:SS'))
AND (DATERECORDED  >= TO_DATE('20/06/2013 06:00:00', 'DD/MM/YYYY HH24:MI:SS')) 
AND (DATERECORDED < TO_DATE('20/06/2013 12:00:00', 'DD/MM/YYYY HH24:MI:SS'))

クエリは動的に生成され、動的な値は次のとおりです。

where 句 (DATESEEN) の 2 行目は 90 日前です。
where 句の 3 行目は、クエリが最後に実行された時刻です。(通常は 12 時間前)
where 句の最後の行は現在の時刻です。

DATERECORDED にはインデックスがありませんが、DATESEEN にはあります。どうしようもない理由で、DATERECORDED にインデックスを付けることができません。

WHERE 句の「DATESEEN」行は完全に冗長ですか? DATESEEN は常に DATERECORDED よりかなり前の日付になるため、無視されますか? 実行計画はほとんど明らかにしません。 実行計画

前もって感謝します!

4

2 に答える 2

1

にインデックスがありませんDateRecorded。句を満たすためにwhere、Oracle は全テーブル スキャンを実行し、すべてのレコードを読み取る必要があります。

インデックスは、完全なテーブル スキャンを防ぐことがdeletedできDateSeenますDateRecorded

これら 2 つのフィールドにインデックスがない場合、句は冗長です。存在する場合、クエリの I/O を大幅に削減できます。DateRecorded にインデックスを作成するほどではありませんが、特に 10 年または 20 年分のデータがある場合は、かなりの数になる可能性があります。

ただし、Oracle はそのようなインデックスを自由に使用しません。この決定は、テーブルに関して収集された統計に基づいています。

もう 1 つの考慮事項は、パーティショニングです。テーブルが によってパーティション分割されている場合DateSeen、それをwhere句に含めることで、データベースはクエリを満たす適切なパーティションを選択できます。これは、他の列では不可能です。

于 2013-06-20T17:07:55.597 に答える
0

この行:

AND (DATERECORDED  >= TO_DATE('20/06/2013 06:00:00', 'DD/MM/YYYY HH24:MI:SS')) 

追加のフィルタリングが追加されるため、冗長ではありません。

この行:

AND (DATERECORDED < TO_DATE('20/06/2013 12:00:00', 'DD/MM/YYYY HH24:MI:SS'))

冗長かもしれません。記録された日付が常に過去にあり、常に現在の日付よりも前の日付をチェックしている場合は、そうです。

あなたのdateeen行は冗長かもしれませんし、そうでないかもしれません。フィルタリングを追加したり、クエリを高速化したりする場合は、そうではありません。それ以外の場合は、si.

于 2013-06-20T16:54:42.973 に答える