我们对以下症状感到恼火。我们非常感谢您就其原因及解决方法提出的任何建议。
我运行下面的简单查询,Oracle DB需要3,800秒才能返回结果,而同一查询在几秒钟内在具有相同表的SQL Server数据库中完成。 (它用作数据集市)。
查询:
select
T_X.Col1
,(select count(1) from T_X where T_X.colX = T_Y.colY) as cnt1
from T_Y
记录次数:
T_X:96,536
T_Y:129,359
其他信息:
-ColY是T_Y的主键,两个环境中的ColXin都没有索引。
-Oracle 11.1(使用SQL Developer运行查询)
-SQL Server 2008(使用SSMS运行查询)
- 两种环境之间的硬件规格差异不大。
- 上面的查询是较大的一部分。我们对其进行了简化,发现该部分是瓶颈。
我们非常感谢您的建议!
其他信息(查询的目的)
上面的查询是下面查询的一部分。我们的目的是找出T_Y中的记录(计数),这些记录在其他表中没有对应的记录(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
;
执行计划 - Oracle(原始查询)(执行解释计划)
"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" "" "" "" "" ""
执行计划 - SQL Server(原始查询)
第7行表示SQL Server使用Clustered Index Scan而不是Table Scan,尽管聚簇索引不包含ColumnY。有谁能解释这是什么意思? 我是否可以强制Oracle使用类似的执行计划使用提示条款或其他任何内容?
|--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]))
答案 0 :(得分:0)
您需要t_x(colX)
上的索引。我猜这个索引存在于SQL Server上。
这两个版本的版本可能更快:
select t_x.colX, count(1)
from T_X
group by t_x.colX;
它不完全相同,但它可能是你真正想要的。
答案 1 :(得分:0)
我们的目的是找出T_Y中的记录(计数)在其他表中没有对应记录(T_A,T_B,T_C,T_D,T_E,T_X)。
最好表达为:
select
count(*)
from
T_Y
where ColH in ('X') and
not exists (select null from T_A A where A.ColA = T_Y.ColY) and
not exists (select null from T_B B where B.ColB = T_Y.ColY) and
not exists (select null from T_X where T_X.ColX = T_Y.ColY) and
not exists (select null from T_C C where C.ColC = T_Y.ColY) and
not exists (select null from T_D D where D.ColD = T_Y.ColY) and
not exists (select null from T_E E where E.ColE = T_Y.ColY);