110

假设我在数据库中有一个 ID 行 (int) 作为主键。如果我经常查询 ID,是否还需要对其进行索引?还是它是主键意味着它已经被索引?

我问的原因是因为在 MS SQL Server 中我可以在这个 ID 上创建一个索引,正如我所说的,这是我的主键。

编辑:一个额外的问题 - 额外索引主键有什么害处吗?

4

11 回答 11

75

没错,SQL Server 允许您在相同字段上创建重复索引令人困惑。但是您可以创建另一个的事实并不表示 PK 索引也不存在。

额外的索引没有好处,但唯一的危害(非常小)是额外的文件大小和行创建开销。

于 2009-01-20T18:51:54.483 回答
56

正如其他人已经说过的,主键是自动索引的。

仅当您需要优化使用主键和其他一些特定列的查询时,在主键列上创建更多索引才有意义。通过在主键列上创建另一个索引并包含其他一些列,您可能会达到查询所需的优化。

例如,您有一个包含许多列的表,但您只查询 ID、名称和地址列。以 ID 作为主键,我们可以创建以下索引,该索引建立在 ID 之上,但包含 Name 和 Address 列。

CREATE NONCLUSTERED INDEX MyIndex
ON MyTable(ID)
INCLUDE (Name, Address)

因此,当您使用此查询时:

SELECT ID, Name, Address FROM MyTable WHERE ID > 1000

SQL Server 将仅使用您创建的索引为您提供结果,它不会从实际表中读取任何内容。

于 2009-01-20T19:01:40.360 回答
28

注意:这个答案解决了大型企业级开发。

这是一个 RDBMS 问题,而不仅仅是 SQL Server,其行为可能非常有趣。一方面,虽然主键自动(唯一)索引很常见,但它不是绝对的。 有时必须不唯一索引主键。

在大多数 RDBMS 中,如果主键不存在,则会自动在主键上创建唯一索引。因此,您可以在将主键列声明为主键之前在主键列上创建自己的索引,然后当您应用主键声明时,数据库引擎将使用该索引(如果可接受)。通常,您可以创建主键并允许创建其默认唯一索引,然后在该列上创建自己的备用索引,然后删除默认索引。

现在是有趣的部分——你什么时候不想要一个唯一的主键索引?当您的表获取足够的数据(行)以使索引的维护过于昂贵时,您不想要也不能容忍一个。这取决于硬件、RDBMS 引擎、表和数据库的特性以及系统负载。但是,它通常会在表格达到几百万行时开始显现。

本质问题是每次插入行或更新主键列都会导致索引扫描以确保唯一性。随着表的增长,唯一索引扫描(或其在任何 RDBMS 中的等效项)变得更加昂贵,直到它主导表的性能。

我已经多次处理过这个问题,表有 20 亿行,8 TB 的存储空间,每天有 4000 万行插入。我的任务是重新设计所涉及的系统,其中包括实际上作为第一步删除唯一主键索引。事实上,在我们甚至接近重新设计之前,为了从中断中恢复,在生产中删除该索引是必要的。重新设计包括寻找其他方法来确保主键的唯一性并提供对数据的快速访问。

于 2009-01-20T20:07:55.733 回答
23

默认情况下,主键总是被索引。

您可以使用 SQL Server Management Studio 或 Transact-SQL 在 SQL Server 2012 中定义主键。创建主键会自动创建相应的唯一、聚集或非聚集索引。

http://technet.microsoft.com/en-us/library/ms189039.aspx

于 2009-01-20T18:29:54.963 回答
9

这里来自MSDN的段落:

为表指定 PRIMARY KEY 约束时,数据库引擎通过为主键列创建唯一索引来强制数据唯一性。此索引还允许在查询中使用主键时快速访问数据。因此,选择的主键必须遵循创建唯一索引的规则。

于 2009-01-20T18:34:29.260 回答
8

除非您指定非聚集索引,否则 PK 将成为聚集索引

于 2009-01-20T18:30:30.920 回答
5

声明PRIMARY KEYorUNIQUE约束会导致 SQL Server 自动创建索引。

可以在不匹配约束的情况下创建唯一索引,但如果没有唯一索引,则不能存在约束(主键或唯一)。

从这里开始,约束的创建将:

  • 导致创建同名索引
  • 拒绝删除创建的索引,因为没有它就不允许存在约束

同时删除约束将删除关联的索引。

PRIMARY KEY那么, a或之间是否存在实际区别UNIQUE INDEX

  • NULL值不允许在 中PRIMARY KEY,但允许在UNIQUE索引中;和集合运算符(UNION、EXCEPT、INTERSECT)一样,NULL = NULL这意味着您只能有一个值,因为两个NULLs 彼此重复;
  • PRIMARY KEY每个表只能存在一个,而可以创建999个唯一索引
  • 创建约束时PRIMARY KEY,除非表上已经存在聚集索引或NONCLUSTERED在其定义中使用,否则将其创建为聚集索引;创建索引时UNIQUE,它被创建为NONCLUSTERED除非它不是特定的CLUSTERED并且这样的已经不存在;
于 2018-11-29T19:22:39.063 回答
2

使其成为主键也应该自动为其创建索引。

于 2009-01-20T18:30:33.887 回答
1

在 SQL Server 中,一般来说,主键是自动索引的。这是真的,但它不能保证更快的查询。当只有 1 个字段作为主键时,主键将为您提供出色的性能。但是,当有多个字段作为主键时,索引是基于这些字段的。

例如:字段 A、B、C 是主键,因此当您根据 WHERE CLAUSE 中的这 3 个字段进行查询时,性能很好,但是当您想在 WHERE CLAUSE 中仅使用 C 字段进行查询时,您不会有好的表现。因此,为了让您的性能启动并运行,您需要手动索引 C 字段。

大多数情况下,在您达到超过 100 万条记录之前,您不会看到问题。

于 2011-09-19T23:42:06.670 回答
0

主键被自动索引

您可以根据您的使用情况使用 pk 创建其他索引

  • 如果您经常按 zip_code 和 id 选择 index zip_code, id 可能会有所帮助
于 2009-01-20T18:29:45.090 回答
0

我有一个没有(单独)索引的庞大数据库。

每当我通过主键查询时,出于所有密集目的,结果都是即时的。

于 2009-01-20T18:30:11.467 回答