0
SELECT  A.Id, AMerge.FeildA, AMerge.FeildB, AMerge.FeildC, BMerge.FeildD, BMerge.FeildE, BMerge.FeildF, 
FROM 

    (SELECT Id, FieldA, FieldB, FieldC from A1
    UNION ALL 
    SELECT Id, FieldA, FieldB, FieldC from A2
    ) AS A
    INNER JOIN 
    (
    SELECT Id, FieldD, FieldE, FieldF FROM B1
    UNION ALL 
    SELECT Id, FieldD, FieldE, FieldF FROM B2
    )  AS B

ON A.Id = B.Id

其中 A 的 n = 8102869,B 的 n = 17935860,导致表大小 n=17935860。

如何重构此查询以提高效率,或者我可以对表或数据库执行哪些流程以提高上述查询的性能?

4

2 回答 2

1

你能发布查询计划吗?

确保所有表上的 id 上都有一个聚集索引并重构为以下内容可能会加快速度。查询中有很多合并连接并且没有排序可能是您可以摆脱这种情况的最佳计划。

Select
  a1.Id, a1.FieldA, a1.FieldB, a1.FieldC, b1.FieldD, b1.FieldE, b1.FieldF
From 
  A1 Inner Join B1 On A1.ID = B1.ID
Union All
Select
  ...
From
  A2 Inner Join B1 On A2.Id = B1.ID 
Union All 
Select
  ...
From
  A1 Inner Join B2 On A1.Id = B2.ID
Union All
Select
  ...
From
  A2 Inner Join B2 On A2.ID = B2.ID

此外,您已经标记了这个 mysql 和 sql-server。我这里说的是Sql Server,对mysql的来龙去脉还不够了解

于 2012-11-08T23:24:21.330 回答
0

首先,您需要在所有表上都有一个聚集索引。如果没有聚集索引,您的表就是一个堆,任何查询都会进行表扫描——这是它检查所有行的唯一方法。

其次,您应该有一个(复杂/多列)索引,至少涵盖您在任何连接中使用的任何列:理想情况下,首先是最细粒度的列,等等。

因此,如果您没有此 SQL,则会将每个表中的列数相乘并尝试创建结果的临时表。

因此,如果您在 1 个表中有 100000 行,而在另一个表中有 10000 行,则计算出的没有索引的行大小将是 1000000000 行。天知道会创建多大的临时表!

使用索引(和最新的统计数据),如果一个表中有 100 行,另一个可能匹配的 10 行,SQL 将估计 1000 行。它可以将其存储在您的临时数据库中,更不用说运行速度更快!

于 2012-11-09T16:09:41.343 回答