【问题标题】:Unioning Pseudo-partitioned tables into a single view将伪分区表合并到一个视图中
【发布时间】:2011-10-07 15:30:09
【问题描述】:

假设我们有 5 张桌子

Fact_2011
Fact_2010
Fact_2009
Fact_2008
Fact_2007

每个都只存储表名称扩展所指示的年份的事务。

然后,我们在这些表中的每一个上创建一个单独的索引,并将“Year”列作为索引的第一列。

最后,我们创建一个视图vwFact,它是所有表的联合:

SELECT * FROM Fact_2011
UNION
SELECT * FROM Fact_2010
UNION
SELECT * FROM Fact_2009
UNION
SELECT * FROM Fact_2008
UNION
SELECT * FROM Fact_2007

然后执行如下查询:

SELECT * FROM vwFact WHERE YEAR = 2010

或者在不太可能的情况下,

SELECT * FROM vwFact WHERE YEAR > 2010 

这些查询与实际按年份对数据进行分区相比效率如何,还是基本相同?在这些伪分区表中的每一个上都有一个由Year 编制的索引,以防止 SQL 引擎浪费大量时间来确定包含搜索日期范围之外的记录的物理表是不值得的扫描?还是这种伪分区方法正是 MS 分区(按年份)所做的?

在我看来,如果执行的查询是

SELECT Col1Of200 FROM vwFact WHERE YEAR = 2010 

真正的分区将具有明显的优势,因为伪分区首先必须执行视图以从Fact_2010 表中拉回所有列,然后过滤到最终用户正在选择的一列,而使用 MSSQL 分区时,它更像是直接预先选择仅查找的列的数据。

评论?

【问题讨论】:

标签: sql-server-2008 database-partitioning


【解决方案1】:

我已经成功地在 SQL Server 2000 上实现了分区视图

确保您对每个表都有一个检查约束,将年份列限制为年份。所以在 Fact_2010 表上,它将是 Check Year = 2010

然后也使视图 UNION ALL 不仅仅是 UNION

现在,当您查询一年的视图时,它应该只访问 1 个表,您可以使用执行计划来验证这一点

如果您没有适当的检查约束,它将触及作为视图一部分的所有表

真正的分区将具有明显的优势,因为 伪分区首先必须执行视图以拉回所有 Fact_2010 表中的列,然后过滤到 最终用户正在选择的列

如果你有适当的约束,优化器足够聪明,可以只处理你需要的表

【讨论】:

  • 假设您的“确保”评论是真实的(我希望它会是):-),这是一个很好的信息,对我来说,一个令人惊讶的事实!事后思考:在所有 FACT 表的 UNION 上的 YEAR 索引视图是否比在每个物理表上的 Year 单独索引更合适?此外,虽然 UNION ALL 更加明确和更好的选择,但我不知道 UNION 如何在给定约束的情况下返回不同的结果。评论?非常感谢您的回答。我喜欢它。
  • 必须维护索引视图,因此您的所有更新删除和插入都会变慢..您还需要更多的数据库空间来存储该视图
  • @Chad:关于 UNION ALL 与 UNION,这不是关于结果是否会不同,而是关于摆脱 UNION 所做的绝对不必要的排序(因为隐含的 DISTINCT)。跨度>
猜你喜欢
  • 2013-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多