Wir sind genervt von dem Symptom unten. Wir freuen uns über jeden Hinweis von Ihnen über die Ursache und die Art und Weise, wie Sie diese beheben können.Eine langsame Abfrage in Oracle (läuft in SQL Server schnell) (eine korrelierte Unterabfrage)
Ich führe die einfache Abfrage unten und es dauerte 3.800 Sekunden für Oracle DB, um das Ergebnis zurückzugeben, während die gleiche Abfrage in ein paar Sekunden in einer SQL Server-Datenbank, die die gleichen Tabellen hat abgeschlossen. (Es wird als Datamart verwendet).
Abfrage:
select
T_X.Col1
,(select count(1) from T_X where T_X.colX = T_Y.colY) as cnt1
from T_Y
Aufzeichnungen zählen:
t_x: 96.536
T_Y: 129.359
Weitere Informationen:
-ColY ist der Primärschlüssel von T_Y und es gibt keinen Index für ColXin in beiden der beiden Umgebungen.
-Oracle 11.1 (lief die Abfrage SQL Developer verwenden)
-SQL Server 2008 (lief die Abfrage mit SSMS) zwischen den beiden Umgebung
-Nr große Unterschiede von Hardware-Spezifikationen.
-Die obige Abfrage ist ein Teil des größeren. Wir haben es vereinfacht und festgestellt, dass der Teil der Engpass war.
Wir würden uns über Ihren Ratschlag freuen!
Zusätzliche Informationen (der Zweck der Abfrage)
Die Abfrage oben ist ein Teil der unter Abfrage. Unser Zweck besteht darin, Datensätze (die Anzahl von) in T_Y herauszufinden, die keine Korrespondenzaufzeichnungen in anderen Tabellen haben (T_A, T_B, T_C, T_D, T_E, T_X).
select
count(1)
from
(select
T_Y.ColA
,T_Y.ColG
,T_Y.ColH
,(select count(1) from T_A A where A.ColA = T_Y.ColY) as cnt1
,(select count(1) from T_B B where B.ColB = T_Y.ColY) as cnt2
,(select count(1) from T_X where T_X.ColX = T_Y.ColY) as cnt3
,(select count(1) from T_C C where C.ColC = T_Y.ColY) as cnt4
,(select count(1) from T_D D where D.ColD = T_Y.ColY) as cnt5
,(select count(1) from T_E E where E.ColE = T_Y.ColY) as cnt6
from T_Y
)XXX
where 1=1
and XXX.ColH in ('X')
and XXX.cnt1 = 0
and XXX.cnt2 = 0
and XXX.cnt3 = 0
and XXX.cnt4 = 0
and XXX.cnt5 = 0
and XXX.cnt6 = 0
;
Ausführungsplan - Oracle (für die ursprüngliche Abfrage) (Execute-Plan Erklären)
"Optimizer" "Cost" "Cardinality" "Bytes" "Partition Start" "Partition Stop" "Partition Id" "ACCESS PREDICATES" "FILTER PREDICATES"
"SELECT STATEMENT" "ALL_ROWS" "121" "129359" "776154" "" "" "" "" ""
"SORT(AGGREGATE)" "" "" "1" "6" "" "" "" "" ""
"TABLE ACCESS(FULL) XXXXX.T_X" "ANALYZED" "6616" "2" "12" "" "" "" "" ""T_X"."ColX"=:B1"
"INDEX(FAST FULL SCAN) XXXXX.T_Y_0" "ANALYZED" "121" "129359" "776154" "" "" "" "" ""
Ausführungsplan - SQL Server (für die ursprüngliche Abfrage)
Linie 7 gibt an, dass SQL Server Clustered Index Scan anstelle von Table Scan verwendet, obwohl der Clustered-Index ColumnY nicht enthält. Könnte jemand erklären, was das bedeutet? Kann ich Oracle dazu zwingen, den ähnlichen Ausführungsplan mit einer Hinweisklausel oder irgendetwas zu verwenden?
|--Compute Scalar(DEFINE:([Expr1008]=CASE WHEN [Expr1006] IS NULL THEN (0) ELSE [Expr1006] END))
|--Parallelism(Gather Streams)
|--Hash Match(Right Outer Join, HASH:([DB_X].[dbo].[T_X].[ColX])=([DB_X].[dbo].[T_Y].[ColY]), RESIDUAL:([DB_X].[dbo].[T_X].[ColX]=[DB_X].[dbo].[T_Y].[ColY]))
|--Compute Scalar(DEFINE:([Expr1006]=CONVERT_IMPLICIT(int,[Expr1013],0)))
| |--Hash Match(Aggregate, HASH:([DB_X].[dbo].[T_X].[ColX]), RESIDUAL:([DB_X].[dbo].[T_X].[ColX] = [DB_X].[dbo].[T_X].[ColX]) DEFINE:([Expr1013]=COUNT(*)))
| |--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([DB_X].[dbo].[T_X].[ColX]))
| |--Clustered Index Scan(OBJECT:([DB_X].[dbo].[T_X].[PK_T_X]))
|--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([DB_X].[dbo].[T_Y].[ColY]))
|--Clustered Index Scan(OBJECT:([DB_X].[dbo].[T_Y].[PK_T_Y]))
Ihre Anfrage ist verwirrend. Beschreibe in Worten, was deine Intention ist - das hilft manchmal. –
Korrektur: colY ist der Primärschlüssel von T_Y. – yobioo
Bitte buchen Sie die Ausführungspläne für die Abfragen in beiden Datenbanken. – sstan