2012-11-08 19 views
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 = 8102869,n = B = 17935860,导致表大小n = 17935860。MSSQL性能 - 连接上的大数n

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

+0

你有什么指标,你有什么数据? – Jester

+0

如果这是MySQL的请用'EXPLAIN SELECT ...'的输出更新你的问题。 – Xint0

回答

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的来龙去脉

+0

修复了标签,我正在为4个表设置主键。第一个表格需要15分钟+来添加约束。我的理解是,创建主键实际上与在可空的字段上创建聚集索引相同。我会尝试重构。查询运行了70分钟,然后我得到了“磁盘空间不足错误”,可能是由于本地计算机上缺少空间。我将清除空间,添加约束,重构,然后重试。您对给定查询的执行时间窗口有猜测吗? – sammarcow

+0

呃没有主键和聚簇索引是不一样的。 –

+0

这就是说他们是。 [主键与唯一聚簇索引](http://www.sql-server-performance.com/forum/threads/primary-key-vs-unique-clustered-index.24320/)。也许你可以提供一些更有建设性的东西来添加... – sammarcow

0

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

其次,你应该有一个(复/穆蒂COL)指数至少覆盖您在任何使用任何列连接:最好用最精细列第一等

因此,如果你没有这个SQL将mutiply的尝试创建结果的临时表。

因此,如果您在一个表中有100000行并且在另一个表中有10000行,则计算的没有索引的行大小将为1000000000行。天知道什么大小的临时表将创建!

如果在一个表中有100行,而在另一个表中有10行可能匹配,则索引(和统计数据)将估计为1000行。它可以存储在你的临时数据库中,而不是说运行速度更快!

+0

Ian,你确定我需要另外创建一个聚集索引......查看你的文档链接......“索引是在PRIMARY时自动创建的KEY和UNIQUE约束是在表列上定义的,例如,当您创建一个表并将特定列标识为主键时,数据库引擎会自动在该列上创建一个PRIMARY KEY约束和索引。有关更多信息,请参阅创建索引(数据库引擎)“。在[http://msdn.microsoft.com/en-us/library/ms190457(v=sql.105).aspx](http://msdn.microsoft.com/en-us/library/ms190457(v= sql.105).aspx) – sammarcow

+0

就像所有的SQL问题一样,这取决于。我们的共识是:你总是需要一个聚集索引,但这可能是唯一的,并且覆盖多个列。即使它只在一列上,例如DATE列(与日期时间相反)多个条目可能具有相同日期时,MSSQL也会创建一个Uniquifying条目。聚集索引决定了存储行的顺序,所以如果您有一个订购表DayTaken和DayDelivered,您可以选择一个或自动增量标识列。它不是唯一指数的最佳做法不仅仅是作为行指标。 –

+0

cont ..聚集索引不需要重新安排/重新打包,所以在上面的例子中DateTaken会很好,但是DateDelvered可能需要在物理移动行的情况下进行半定期重组。由于索引和这些索引的统计信息的工作方式:自动增加col可以提供更好的插入性能,需要较少的主要性并在给定适当的支持索引并保持统计信息的情况下提供良好的查询性能。它是一个很大的主题和专家为大型组织赚取大量资金调整数据库。 –