SQL Server:UNION ALL vs将所有列聚合到一个表中

时间:2013-08-06 16:59:26

标签: sql sql-server tsql

我对两个设计的性能有疑问。目标是存储多种类型的实体,它们共享某些属性但也有所不同。

方法1:多个表,每个表为一个实体建模

Entity1 - C1, C2, C3
Entity2 - C1, C2, C4
Entity3 - C1, C2, C5    

要查询,我需要在所有表格上执行UNION ALL

方法2:包含所有列和类型列的单个表

All - Type, C1, C2, C3, C4, C5

在这里,我可以直接查询列。

问题是UNION ALL方法是否存在任何性能问题?这个问题类似于PostsgreSQL上的previously asked question,但尚未得到解答。

编辑:

感谢您的所有答案。

实体表是日期索引。并且查询大多数是按时间过滤的,或者是过滤的共享字段。假设C1是日期,C2是字符串,95%的查询看起来像C1> = from和C1< = to,或C2 ='SomeId'。

记录数量增长缓慢,每个实体每天可能有几百个。列数不会超过150.但是,共享列的数量很少。目前我已经实现了方法1,因为每个实体可以使用除共享之外的字段作为主键。这种约束更自然。

3 个答案:

答案 0 :(得分:2)

在做出这个选择时,它在很大程度上取决于表需要的宽度,是否存在任何共享列,表的大小,对表执行的查询类型等等。

根据经验,如果表格宽度接近数据库支持记录的最大宽度,请不要放入一个表格。较宽的表往往表现更好。如果您谈论的列很少,这可能是最好的解决方案。

如果公共列是最常查询的列,则考虑设计具有公共列的父表和针对特定类型的子表的三个子表。

如果很少有公共列和类型通常很可能会自己查询(类型a和类型B通常都不会出现在最常运行的查询类型的结果集中),那么将表格与在你需要查询所有这些内容的几次UNION all视图都可以工作。

如果您只需要查询所有类型的报告而不是所有普通的日常工作,请考虑使用单独的表和数据仓库进行报告。

答案 1 :(得分:1)

您打算大概有多少行?我有使用像这样的大表的经验,他们采用单表方法,除非你击中其中一个索引(表格大约250列,差不多10亿行),否则获取任何数据的速度都很慢。

由于列的数量,为每个常见的过滤条件构建索引是不切实际的,因为这会大大减慢事务系统上的插入速度。如果这些表是分开的,那么这个例子肯定会容易得多,我们可能会将它们组合在一起,以便我们不得不一起查询所有数据。

但是,我很有意思,需要考虑很多变量。如果您正在使用主要用于OLAP而非OLTP的数据库,那么您可能不会担心添加大量索引等。

答案 2 :(得分:0)

作为替代方案,您可以组合方法1和2,即您可以创建“祖先”表:

All - ID, Type, C1, C2

三个“后代”表,其中ID是PK,同时它是ID All表的FK:

Entity1 - ID, C3
Entity2 - ID, C4
Entity3 - ID, C5