1

アイテムのコレクション (> 100 万) と、それを処理するいくつかの処理を行うシステムがあります。各プロセッサは各項目を 1 回だけ処理する必要があり、プロセッサには階層があります。

私たちの現在の実装は、各プロセッサがすでに行ったことを追跡する「処理済み」テーブルを持つことです。

CREATE TABLE items (id NUMBER PRIMARY KEY, ...)
CREATE TABLE itemsProcessed(
    item NUMBER REFERENCES items(id),
    processor NUMBER)

私たちのクエリはこれです (itemsProcessed関連するインデックスがあります) - NOT IN を使用して、現在のプロセッサまたはその祖先によって既に処理されたアイテムを除外しています。

SELECT ... FROM items i WHERE <additional queries on items>
    AND id NOT IN (SELECT item FROM itemsProcessed WHERE processor IN (1, 2))

処理されたテーブルが非常に大きくなると、最初のアイテムを返し始める前に多くのフィルタリングを行う必要があるため、このクエリは長い時間 (数秒) かかり始めます (クエリ プランはハッシュ アンチジョインを使用しています)。

最初のいくつかの項目を非常に迅速に返すために、このクエリが必要です。理想的には、500ms 未満で最初の項目を返します。これは、反復処理をitems行って 内のものを除外できないことを意味しitemsProcessedます。itemsしたがって、 andの結合で否定インデックスを実行する何らかの方法が必要ですitemsProcessed(これは mongo で達成しましたが、oracle では同様のことができないようです)。

これはオラクルで可能ですか?

4

3 に答える 3

1

/*+ first_rows */ヒントをクエリに追加してみることができます

SELECT /*+ first_rows (10) */... FROM items i ...

または、最初に未処理のアイテムを選択してみてください。<additional queries on items>

with i_to_process AS
(
  SELECT item  FROM items
  minus 
  SELECT item FROM itemsProcessed WHERE processor IN (1, 2)
)
select * from i_to_process
where 
<additional queries on items>
于 2016-09-28T12:55:14.110 に答える
0

テーブルが更新される頻度に応じて、itemsNotProcessed の実体化されたビューを作成できます。処理は事前に行われます。少し非正規化し、処理済みフラグを項目テーブルに追加し、フラグにビットマップ インデックスを追加することもできます。

于 2016-10-07T20:43:12.140 に答える
0

IMO これは設計上の問題です。処理されていないアイテムを含めようとしているときに、既に処理されたアイテムを除外しようとしています。処理されたアイテムのリストは継続的に増加します。処理されるアイテムのリストは小さいままです。処理済みの項目のテーブル (itemsProcessed) を作成するのではなく、処理する項目のテーブルを作成し、それをクエリに内部結合して、処理中に ITEMS_TO_BE_PROCESSED テーブルから項目を削除することをお勧めします。

幸運を祈ります。

于 2016-09-28T11:32:24.410 に答える