Oracle
IN 子句太慢
我一直在尋找大約 1 小時,但我沒有找到任何東西。
我有這個問題:
當我執行此查詢時:
select order_id from or_order@smartflex where order_id in ( select distinct numeroot from oym_planmantenimiento )
太費時間了,我說的差不多一個小時!!!
但是,當我首先執行子查詢時,我將結果導出到 excel(它們總是在 100 或 400 個結果之間),然後我傳遞靜態值,查詢只需要 1 秒:
select order_id from or_order@smartflex where order_id in ( 1230, 1231, 1232, 1233, ..., 1239 )
我想要像子查詢這樣的東西只執行一次,傳遞值,然後另一個查詢開始執行。
我能做些什麼 ?
謝謝
羅伯托 E。
新訊息:
表 or_order 有 78697214 並且還在計數。這每秒都在增長。表 oym_planmantenimiento 最多有 10000 條記錄,但唯一的只有 300~600 條。對於這種情況,它是 358,因為它隨著頻率而變化,但就像每天一樣,而不是每秒。所以對我來說,查詢開頭的靜態值就足夠準確了。
為了第一:
Plan Hash Value : 240660835 ---------------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost | Time | ---------------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 702 | 10530 | 96811 | 00:19:22 | | * 1 | HASH JOIN RIGHT SEMI | | 702 | 10530 | 96811 | 00:19:22 | | * 2 | INDEX FAST FULL SCAN | OYM_PLANMANTENIMIENTO_IDX03 | 832 | 1664 | 6 | 00:00:01 | | 3 | REMOTE | OR_ORDER | 78399636 | 1019195268 | 96367 | 00:19:17 | ---------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): ------------------------------------------ * 1 - access("ORDER_ID"="NUMEROOT") * 2 - filter("NUMEROOT" IS NOT NULL)
對於第二個:
Plan Hash Value : -------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost | Time | -------------------------------------------------------------------------------- | 0 | SELECT STATEMENT REMOTE | | 358 | 2148 | 361 | 00:00:01 | | 1 | INLIST ITERATOR | | | | | | | * 2 | INDEX UNIQUE SCAN | PK_OR_ORDER | 358 | 2148 | 361 | 00:00:01 | --------------------------------------------------------------------------------
OYM_PLANMANTENIMIENTO 有一個索引類型:在列 numeroot 上正常。OR_ORDER 有一個索引類型:在 order_id 上是唯一的。
採用
EXISTS
通常你解決這個問題
EXISTS
SELECT order_id FROM or_order@smartflex AS outer WHERE EXISTS ( SELECT 1 FROM oym_planmantenimiento WHERE numroot = outer.order_id );
失去“與眾不同”。
我經常看到不同的子句被用作不良資料結構的創可貼,但代價是
$$ dire $$表現。 永遠記住distinct 會刪除重複項,所以…
select distinct a, b, c from ...
……可能和……一樣貴
select a, b, c from ... group by a, b, c order by a, b, c
數據庫不需要不同的值來滿足“in”子句,強制它使用一個只會增加它必須做的工作,並強制它以特定的順序完成這項工作。瓶頸,有人嗎?
當然,您最好的解決方案是使用 join …
select order_id from or_order@smartflex t1 inner join oym_planmantenimiento t2 on t1.order_id = t2.numeroot
…但我注意到您在這裡使用了數據庫連結,因此這可能是不可能的。