2

Ordersフィールドを持つ注文を格納するテーブルがあります。

Id          
Date        
Amount      
Cost
Currency

次のクエリを試しました。

SELECT SUM(Amount)-SUM(NFC1)
FROM Orders
WHERE Date BETWEEN '20121101' AND '20121231'
      AND Currency = 'EUR'

現在、Oracle SQL Developer によるとCurrency = 'EUR'、他の操作のコストがはるかに低いため、クエリが遅くなるのはフィルターです。

インデックスを確認したところ、 にインデックスがありId、 に別のインデックスがありDateます。クエリ分析によると、DBMS は最初に必要な日付に一致するレコードを見つけてから、テーブル全体をスキャンして、Currency='EUR'. CurrencyですVARCHAR

クエリを最適化する方法はありますか? つまり、フルスキャンを回避する方法はありますか?

一般的な観点から、レコードが日付でフィルター処理された後に DBMS がフル テーブル スキャンを実行するのを防ぎ、日付でフィルター処理されたレコードの中から一致するレコードを見つけることは可能Currencyですか?

どうもありがとう

4

3 に答える 3

2

クエリ分析によると、DBMS は最初に必要な日付に一致するレコードを見つけてから、テーブル全体をスキャンして Currency='EUR' を持つレコードを見つけているようです。通貨は VARCHAR です。

テーブル全体をスキャンするわけではありません。

代わりに、インデックス レコードから行ポインタ (rowidPRIMARY KEYテーブルが IOT の場合は値) を取得し、ネストされたループでテーブル行の通貨を検索します。使用しているインデックスには が含まれていないCurrencyため、フィルタリングを行うには何らかの方法で検索する必要があります。

これを回避するには、複合インデックスを作成する必要があります(Currency, Date)

別のインデックスを作成できない場合は、MATERIALIZED VIEWを作成して、その上にインデックスを作成してみてください。

于 2013-01-13T01:32:16.027 に答える
0

クエリを最適化する方法はありますか? つまり、フルスキャンを回避する方法はありますか?

フル スキャンは、利用可能な最も最適化されたプランである可能性があります。テーブルの大部分からのデータのフィルタリングは、通常、テーブルを完全にスキャンすることで高速になります。データベースは、高速のシーケンシャル ディスク読み取りを使用できます。

于 2013-01-13T09:07:52.683 に答える
0

両方のフィールドを使用して頻繁にフィルタリングする場合は、フィールドにインデックスを構築するCurrencyか、複合インデックスをDate構築しますCurrency

于 2013-01-13T00:36:32.933 に答える