我們已經有了一個系統,其中包含一系列項目(> 100萬)以及處理它的幾件事情。每個處理器應該只處理每個項目一次,並且處理器具有層次結構。非常快速地從NOT IN查詢中返回結果
我們當前的實現是有一個什麼樣的每個處理器已經做了「處理」表保持跟蹤:
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))
當處理表變得非常大,這個查詢開始花費很長的時間(幾秒鐘),因爲它做很多過濾bef它開始返回第一個項目(查詢計劃使用散列抗連接)
我們需要此查詢以非常快的速度返回前幾個項目 - 理想情況下返回500ms內的第一個項目。這意味着它不能遍歷items
並過濾掉itemsProcessed
中的那些。因此,我們需要做的加盟items
和itemsProcessed
否定指標的某些方面(我們已經在蒙戈做到了這一點,但甲骨文似乎好好嘗試一下才能夠做類似的事情)
這可能與甲骨文?
如果這能給出更好的結果,你可以試試嗎? 'AND ID IN(SELECT item FROM itemsProcessed WHERE processor> 2)'。如果你的'processor'永遠不是'NULL',它應該返回相同的結果,但是不用'NOT'表示,在某些情況下可能更好地使用索引 –
你的外鍵索引 - 是你說你有一個「相關」索引,或者你只索引了'processor'?它們是什麼類型的索引?執行計劃顯示了什麼?你是否試過使用'not exists'而不是'rownum'停止鍵,如果你只想要前幾個未處理的rows? –
查詢所需的時間還取決於您在<對項目的附加查詢>中所做的操作。是否在表上使用索引? –