SQL Server 中的插入/更新/删除语句应使用哪种类型的索引(聚集/非聚集)。我知道它会产生额外的开销,但与非聚集索引相比,它的性能更好吗?SQL Server 中的 Select 语句还应该使用哪个索引?
2 回答
不能 100% 确定您希望听到什么 - 您只能在一个表上拥有一个集群索引,并且默认情况下,每个表(极少有边缘情况例外)都应该有一个。所有索引通常对您的 SELECT 有最大的帮助,而有些索引往往会稍微伤害 INSERT、DELETE 和可能的 UPDATE(如果选择不当,则可能会伤害很多)。
对于每个操作,聚集索引使表更快。是的!确实如此。有关背景信息,请参阅 Kim Tripp 的优秀聚集索引辩论继续。她还提到了她对聚集索引的主要标准:
- 狭窄
- 静态(从不改变)
- 独特的
- 如果可能的话:不断增加
INT IDENTITY 完美地实现了这一点 - GUID 没有。有关广泛的背景信息,请参阅GUID 作为主键。
为什么窄?因为聚集键被添加到同一张表上每个非聚集索引的每个索引页(如果需要,以便能够实际查找数据行)。你不想在你的集群键中有 VARCHAR(200)....
为什么独一无二??见上文 - 群集键是 SQL Server 用于唯一查找数据行的项和机制。它必须是独一无二的。如果您选择一个非唯一的集群键,SQL Server 本身会为您的键添加一个 4 字节的唯一符。小心那个!
下一个:非聚集索引。基本上有一个规则:引用另一个表的子表中的任何外键都应该被索引,它会加速 JOIN 和其他操作。
此外,任何具有 WHERE 子句的查询都是一个很好的候选者——选择那些首先执行的查询。在 ORDER BY 语句中的 WHERE 子句中显示的列上放置索引。
下一步:测量您的系统,检查 DMV(动态管理视图)以获取有关未使用或缺失索引的提示,并一遍又一遍地调整您的系统。这是一个持续的过程,你永远不会完成!
另一个警告:使用大量索引,您可以使任何 SELECT 查询运行得非常快。但与此同时,必须更新所有相关索引的 INSERT、UPDATE 和 DELETE 可能会受到影响。如果你只选择 - 发疯!否则,这是一种微妙而微妙的平衡行为。您总是可以难以置信地调整单个查询 - 但您系统的其余部分可能会因此而受到影响。不要过度索引您的数据库!放置一些好的指标,检查并观察系统的行为,然后可能再添加一两个,然后再次:观察整体系统性能如何受其影响。
我不太确定“应该用于插入/更新/删除语句”是什么意思,但我认为每个表都应该有一个聚集索引。聚集索引指定数据实际存储的顺序。如果未定义聚集索引,则数据将简单地存储在堆中。如果您没有自然列作为聚集索引,您总是可以像这样将标识列创建为 int 或 bigint。
CREATE TABLE [dbo].[demo](
[ID] [int] IDENTITY(1,1) NOT NULL,
[FirstName] [nchar](10) NULL,
[LastName] [nchar](10) NULL,
[Job] [nchar](10) NULL,
CONSTRAINT [PK_demo] PRIMARY KEY CLUSTERED
(
[ID] ASC
))