Oracle

IN 子句太慢

  • August 8, 2018

我一直在尋找大約 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

…但我注意到您在這裡使用了數據庫連結,因此這可能是不可能的。

引用自:https://dba.stackexchange.com/questions/188815