繁体   English   中英

SQL Server 2008中的索引视图

[英]Indexing Views in SQL Server 2008

我有一个有几亿行数据的表。 有一个名为EventId的字段,它是一个整数字段。

我有许多不同的视图,它们只返回具有特定EventId的数据

如果我运行查询

SELECT TOP 1000 * FROM vw_MyView 

返回行需要5分钟。 添加索引需要什么? 目前有上主表索引的主键(群集上LogId )和非群集上EventId为被每个视图的where子句中被使用。

我知道可以索引视图 - 我应该在视图中索引哪些字段? 我应该只运行数据库引擎优化向导并查看它的内容吗?

更新以下反馈

我的主表及其中的所有数据都沿着以下模式的行

LogId (int) PK
EventId (int)
Param1 varchar(255)
Param2 varchar(255)
..
..
..
Param24 varchar(255)

每个事件类型都有不同的参数,因此主表中包含通用字段名称。

我对每种类型的事件都有一个视图,其中主表中的ParamX字段通过视图被赋予了正确的字段名称。

所以一个事件的观点就像是

SELECT LogId, Param1 AS Name, Param2 AS Address1, Param3 AS Address2
WHERE EventId = 10

我试过了这个问题

SELECT TOP 1000 LogId from vw_MyView 

而且工作得很快。 这是其他正在放慢速度的领域,我认为归结为索引不佳?

更新2 - 更多信息

以前,每个事件的数据都存储在每个事件的表中。 这意味着添加新事件需要为每个事件添加一个新表。

我将数据批量导入临时表,然后将其移动到我的主表中。 批量导入使其变得快速,但我担心拥有如此大的主表可能意味着查询它变得如此之慢以至于无法使用。

数百万行数据超过10年左右,因此我可能会将前8年的数据转移到另一个数据库进行存档,以便保留最近2年的数据。

所以问题是我是否继续使用主表方法,这种方法不需要维护但可能需要大量索引,或者回到每个事件都有一个表的原始方法?

感谢您的反馈,真的很感激

通常,视图包含的列数多于满足许多不同查询所需的列数,而这些查询可能会直接仅针对相关表和列进行更好的查询。 我在2010年在博客中写过这篇文章。 )在你的情况下,我不认为索引视图会帮助你...你正在编写的查询只会扫描该索引而不是基表上的聚簇索引(和因为你没有进行聚合,所以它将是相同的行数,但可能更少的页面。 我认为更好的解决方案是优化基础表上的索引。

我可能建议的索引应该能够极大地帮助您在事件10的视图中显示的查询:

CREATE NONCLUSTERED INDEX Index_ForViewOnEvent10 
ON dbo.MasterTable(LogID)
INCLUDE(Param1, Param2, Param3)
WHERE EventID = 10;

由于此索引涵盖了查询,并且由于过滤器显着减少了必须扫描的行数,因此这应该是一个明显的改进。

您可以使用/不使用INCLUDE部分进行实验。 从聚簇索引中提取它们可能是有效的。 但我认为以上是最好的选择。

现在,不要在这里进行弹道 - 正如我在下面解释的那样,你并不总是想在表上抛出100个索引以完全满足100个不同的查询 - 在满足查询和不转换你的写入之间找到平衡点进入糖蜜。


我将在数据库引擎优化顾问(DTA)上分享几句话。

这个巫师并不神奇。 运行它并看到它的内容没有任何害处,但你不应该只是采取所有的建议并实施它们。 我建议使用此工具时的一些事情:

  • 确保您提供完整的工作量。 如果你给它一个查询并告诉它根据什么使一个查询执行得更好来创建索引,那么它不会考虑其他查询可能不会从这些索引中受益,或者只有它可以从该索引中受益的其他查询有这个或那个其他专栏。
  • 非常了解DTA将提供的重复项。 它可能提供两个或三个具有相同四个前导键的索引,并且在尾随键或INCLUDE列中只有一个区别。 它也喜欢鼓励大量的INCLUDE列使用,你也需要小心这一点。
  • 添加索引会增加DML(插入/更新/删除)执行的工作,因此您还应该记住工作负载的这些部分。

DBSophic拥有比索引调优向导更好的工具 - 它们考虑了整个工作负载,并且不提供冗余索引。 Qure Analyzer是免费的,提供了Qure Optimizer中可用功能的一部分。

我认为你混淆索引视图视图 索引视图当然可以(必须)具有索引,但这并不意味着您必须使用索引视图才能使SQL Server使用索引。 如果它认为使用索引会更快,它将使用常规视图中基础表上存在的任何索引。

因此,首先检查视图的SQL,并确定哪些索引可以帮助查询更快地执行。 如果您为视图发布SQL,我们可能会提出一些想法。

此外,您的select语句不包含ORDER BY子句,因此它是一个非确定性查询。 换句话说,即使数据没有更改,您在后续运行中也可能会得到不同的结果。

关于EventId列,您可以尝试为其添加索引,但它可能没有帮助。 它取决于该列中数据的基数。

您不应该在具有“数亿行数据”的表上创建索引视图。 常规视图只是存储在数据库中的SQL语句,因此如果从your_view运行select *,则sql server只需更改your_view以进行选择。

如果要索引视图,则必须在数据库上保留数据,这意味着在数据库上生成索引列的物理副本。 你可以想象,如果你有这么多行,它会大大增加存储空间,特别是如果你把这个大表与其他表连接起来的话

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM