[英]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)上分享几句话。
这个巫师并不神奇。 运行它并看到它的内容没有任何害处,但你不应该只是采取所有的建议并实施它们。 我建议使用此工具时的一些事情:
DBSophic拥有比索引调优向导更好的工具 - 它们考虑了整个工作负载,并且不提供冗余索引。 Qure Analyzer是免费的,提供了Qure Optimizer中可用功能的一部分。
您不应该在具有“数亿行数据”的表上创建索引视图。 常规视图只是存储在数据库中的SQL语句,因此如果从your_view
运行select *,则sql server只需更改your_view
以进行选择。
如果要索引视图,则必须在数据库上保留数据,这意味着在数据库上生成索引列的物理副本。 你可以想象,如果你有这么多行,它会大大增加存储空间,特别是如果你把这个大表与其他表连接起来的话
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.