主键和索引

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

我问这个问题的原因是,在 MSSQLServer 中,我可以为这个 ID 创建一个索引,正如我所说的,它是我的主键。

编辑: 一个额外的问题-添加主键索引是否有害?

116818 次浏览

主键被自动索引

you can create additional indices using the pk depending on your usage

  • 如果您经常选择 zip _ code 和 id,id 可能会有帮助

默认情况下始终对主键进行索引。

You can define a primary key in SQL Server 2012 by using SQL Server Management Studio or Transact-SQL. Creating a primary key automatically creates a corresponding unique, clustered or nonclustered index.

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

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

任何时候我通过主键查询结果,对于所有密集的目的来说,都是即时的。

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

Making it a primary key should also automatically create an index for it.

下面是 MSDN的一段话:

When you specify a PRIMARY KEY constraint for a table, the Database Engine enforces data uniqueness by creating a unique index for the primary key columns. This index also permits fast access to data when the primary key is used in queries. Therefore, the primary keys that are chosen must follow the rules for creating unique indexes.

您是对的,SQLServer 允许您在同一个字段上创建重复索引,这令人困惑。但是您可以创建另一个索引的事实并不意味着 PK 索引也不存在。

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

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

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

例如,您有一个包含许多列的表,但是您只查询 ID、 Name 和 Address 列。以 ID 作为主键,可以创建以下基于 ID 但包含 Name 和 Address 列的索引。

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

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

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

SQLServer 只会使用您创建的索引提供结果,而不会从实际的表中读取任何内容。

注意: 这个答案涉及企业级开发 很大

这是一个 RDBMS 问题,而不仅仅是 SQLServer 问题,其行为可能非常有趣。首先,虽然主键被自动(唯一地)索引是常见的,但它不是绝对的。有些时候,主键不能被唯一索引是非常重要的。

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

现在是有趣的部分——什么时候你不想要一个唯一的主键索引?如果您的表获取的数据(行)太多,以至于维护索引的成本太高,那么您不想要一个索引,也不能容忍一个索引。这取决于硬件、 RDBMS 引擎、表和数据库的特征以及系统负载。但是,它通常在一个表达到几百万行时开始显示。

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

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

Well in SQL Server, generally, primary key is automatically indexed. 这是正确的,但它不能保证更快的查询。 当只有一个字段作为主键时,主键将提供出色的性能。 但是,如果有多个字段作为主键,则索引将基于这些字段。

例如: 字段 A、 B、 C 是主键,因此当您基于 WHERE 子句中的这3个字段进行查询时,性能很好, 但是,当您想要在 WHERE 子句中使用 Only C 字段进行查询时,您不会得到很好的性能。因此,要使您的性能正常运行,您将需要手动索引 C 字段。

大多数情况下,只有当你的记录超过100万条时,你才会看到这个问题。

声明 PRIMARY KEYUNIQUE约束将导致 SQLServer 自动创建索引。

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

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

  • cause an index with the same name to be created
  • 拒绝删除创建的索引,因为约束不允许在没有它的情况下存在

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

那么,PRIMARY KEYUNIQUE INDEX之间真的有区别吗:

  • NULL值在 PRIMARY KEY中不允许,但在 UNIQUE索引中允许; 和集合运算符(UNION,EXCEPT,INTERSECT)一样,这里的 NULL = NULL意味着你只能有一个值,因为两个 NULL被发现是彼此的重复;
  • 每个表只能存在一个 PRIMARY KEY,而可以创建 999唯一索引
  • 当创建 PRIMARY KEY约束时,它被创建为聚集的,除非表上已经有一个聚集索引,或者在其定义中使用了 NONCLUSTERED; 当创建 UNIQUE索引时,它被创建为 NONCLUSTERED,除非它不是特定于 CLUSTERED,而且这种索引已经不存在;