私は約1時間探していましたが、何も見つかりませんでした。
私はこの問題を抱えています:
このクエリを実行すると:
select order_id
from or_order@smartflex
where order_id in ( select distinct numeroot from oym_planmantenimiento )
時間がかかりすぎて、約1時間の話です!!!
ただし、最初にサブクエリを実行すると、結果がExcelにエクスポートされ(常に100または400の結果のようになります)、静的な値を渡すと、クエリは1秒しかかかりません。
select order_id
from or_order@smartflex
where order_id in ( 1230, 1231, 1232, 1233, ..., 1239 )
サブクエリのようなものを1回だけ実行し、値を渡してから、他のクエリの実行を開始する必要があります。
私に何ができる ?
ありがとう
ロベルト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)
2番目の場合:
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
);
「明確」を失う。
すべてtoo多くの場合、[dire]パフォーマンスを犠牲にして、貧弱なデータ構造のバンドエイドとして使用される個別の句を確認します。
明確に重複を削除するなので、常に覚えておいてください...
select distinct a, b, c
from ...
...と同じくらい高価になる可能性があります...
select a, b, c
from ...
group by a, b, c
order by a, b, c
データベースは、「in」句を満たすために個別の値を必要とせず、1つだけを使用するように強制することは、実行する必要がある作業を増やすのに役立ちますandは、特定の順序で作業を実行することを強制します。ボトルネック、誰か?
もちろん、最善の解決策は結合を使用することです...
select order_id
from or_order@smartflex t1
inner join oym_planmantenimiento t2
on t1.order_id = t2.numeroot
...しかし、ここではデータベースリンクを使用しているため、不可能である可能性があります。
いくつかのステップでそれを行うことができますか?
CREATE GLOBAL TEMPORARY TABLE my_temp_table
( numeroot ... )
ON COMMIT DELETE ROWS;
insert into my_temp_table (numeroot)
select distinct numeroot from oym_planmantenimiento;
SELECT sf.order_id
FROM or_order@smartflex sf
JOIN my_temp_table x
ON sf.order_id=x.numeroot;
DROP ...;
commit;
もう1つの試みは、非決定的関数を追加してoym_planmantenimientoを具体化することです。私はOracleを知らないので、これはまったく機能しない可能性があります。
WITH y AS ( SELECT numeroot, Rand() as rnd
FROM oym_planmantenimiento )
, x AS ( SELECT distinct numeroot FROM y )
SELECT sf.order_id
FROM or_order@smartflex sf
JOIN x
ON sf.order_id=x.numeroot
;
サブクエリを結合に移動すると、通常は高速になります。ただし、テーブルのクエリには常に、少なくともインデックスと、場合によってはテーブルをスキャンする必要があるため、数値を指定するよりもコストがかかります。両方のテーブルのorder_idにインデックスがありますか?そうでない場合は、追加する必要があります。
SELECT sf.order_id
FROM or_order@smartflex sf
INNER JOIN (select distinct numeroot from oym_planmantenimiento) x
ON sf.order_id=x.numeroot
代わりにこれを試すことができます:
WITH x
AS ( SELECT DISTINCT numeroot
FROM oym_planmantenimiento )
SELECT sf.order_id
FROM or_order@smartflex sf
INNER JOIN x
ON sf.order_id=x.numeroot
ORDER BY 1;
これにより、本質的に、個別の値の一時テーブルが作成されます。