我们每天晚上都有一张工作台,有超过一百万条记录。
这个程序每晚大约需要3个小时才能完成。在procedure
中,我们首先将所有数据插入表中。然后我们对表做了很多更新。
例如:
Update a
Set a.Field1 = b.Field1
From WorkingTable as a JOIN Table2 as b
Where a.ID = b.ID
此时我们没有为WorkingTable
分配任何索引或键。如果我们为Index
分配了Keys
或WorkingTable
,它会更快地运行吗?
由于
答案 0 :(得分:1)
要回答这个问题,您首先需要了解密钥和索引在SQL Server中的工作原理。
默认情况下,主键是群集唯一索引。虽然这确实减慢了插入记录的速度,但减速应该是最小的。性能的真正下降通常来自SQL查询中的where
子句或导致表扫描的DML语句。如果您在初始创建后更新了足够的记录,那么在id
列上添加主键或群集唯一索引将是性能获胜。
确实使用主键或索引的决定归结为这个问题:
谁生成" id"?加载数据或数据库的应用程序?
如果加载数据的应用程序生成" id"值,然后在该列上添加聚簇索引就足够了。
CREATE CLUSTERED INDEX IDX_WorkTable_ID
ON dbo.WorkTable (ID);
如果数据库正在生成这些值,只需创建" id"列是int
类型的主键:
ALTER TABLE [WorkTable] ADD ID INT IDENTITY(1,1);
使用主键,插入,更新和删除仍然非常快。
来自MSDN:
除了少数例外,每个表都应该有一个聚簇索引。除了提高查询性能外,还可以根据需要重建或重组聚簇索引,以控制表碎片。也可以在视图上创建聚簇索引。
相关:Clustered and Nonclustered Indexes Explained
如果需要更新已编制索引的列的值,则索引可能会拖累性能。对这些列值的每次更新都会导致SQL Server重建该索引。
与任何性能增强一样,请进行测试。证据就在布丁中。
<强>结论强>
where
子句中为其他查询或语句创建不需要的列这些是任何SQL查询的基本性能指南。
答案 1 :(得分:0)
它可能运行得更快,但可能没有。索引存在并不能保证它会被使用。
我们假设你的例子中的table2只包含两个记录。那么dbms在WorkingTable.id上使用索引来快速找到两条记录肯定是有意义的。
现在让我们说table2包含的记录数是工作表的10000倍。然后,简单地通过工作表记录进行记录并查找Table2.id的索引可能更有意义。那么你的工作表中不需要索引。
话虽如此:无法保证索引可以加快速度,但也可能。如果它没有,也没有造成任何伤害。正如Luc M在对您的请求的评论中所说的那样:当有必须关注的索引时插入和删除会变慢(但据我了解,此时您已完成插入)。并且更新并选择可以从索引中获利。
所以是的,使用索引(在您的示例的WorkingTable.id上)并查看它们是否有帮助。
答案 2 :(得分:0)
此序列应提高性能(您需要做出准确的时间来确定):
准确测量时间(不要在生产服务器上执行此操作!):</ p>
CHECKPOINT
DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
SET STATISTICS IO, TIME ON