我有下表
EVENT_LOG
:
EVENT_ID: pk, int, not null
TYPEID: fk, int, not null
CATEGORYID: fk, int, null
SOURCE: varchar(255), null
DESCRIPTION: varchar(4000), null
CREATED: datetime, null
我们一直在创建报告,发现性能很糟糕。除了群集之外没有任何索引。我们可以创建它们,但是因为这个表的写入次数超过了它的读数 - 所以有一个计数器称重性能问题。对于报告,我倾向于在每个列上放置索引,因为源和&描述列需要搜索子字符串。
我们想知道indexed view(AKA物化视图)是否是一个选项,其中索引视图将包含EVENT_LOG
表中的所有列,但在视图上创建了适当的索引。这会让我们获得报告的性能,同时不会影响对EVENT_LOG
表的写入吗?
答案 0 :(得分:25)
索引视图将导致与列上的索引相同的问题,因为索引视图需要with schemabinding
,这会直接将其绑定到表,从而禁止您以任何方式更改/更改该表的架构,形状或形式。这包括调整列的大小(例如,从varchar(50)
到varchar(255)
),更改列的数据类型(例如,从double
到decimal(18,5)
)等等。我见过由于这个事实,它们引起了许多意想不到的麻烦。
我的建议是设置一个存储过程或SSIS包,它将为您创建一个每小时左右运行一次的报告表。通过这种方式,您可以将永远爱好的地狱索引,并享受它产生的所有性能优势。我不喜欢现场正在进行的系统报道。我实际上还没有看到必要的情况。出于报告目的,小时信息通常绝对足以完成工作。
答案 1 :(得分:3)
我认为它仍然会影响性能,因为物化视图上的索引需要在某些时候更新 - 它可能不需要与表写同步。
我个人会把索引放在桌面上并自己测量写入性能。您可以猜测那里的索引写入速度会慢多少,但在您实际测量它之前,您只是在猜测。它可能根本没有明显的区别。
答案 2 :(得分:3)
“需要搜索源和描述列以查找子字符串。”
当您在varchar()列上搜索子字符串时,SQL Server不会使用任何索引。(即使您复制表并创建索引) 如果在搜索字符串的开头使用了通配字符,则不使用索引。
我想,如果你需要搜索其中的子串,最好在'Source'和'Description'上创建一个全文索引。
所以我的建议是在varchar()列上创建一个全文索引并将Change-Tracking设置为Manual并在没有DML的情况下每小时运行一次...这将减少INSERT上的Loads语句
答案 3 :(得分:1)
如果您经常要写信,那就不是了,因为您在物化视图中有索引的性能成本。物化视图更适用于不经常更改的数据。
答案 4 :(得分:1)
我遇到了类似的问题。决定根据DBA的建议添加多列索引。在我的开发机器和服务器上(具有DBA权限),写入增加和报告的性能比在单个列上创建索引要快得多(17倍)。为什么,我不知道,因为我不是DBA,但我知道基础知识,有时这可以帮助你看透森林/树木。因此,我同意Eric Pertroelje的观点,您必须添加索引并测量写入性能,甚至测量读取性能。