sql主键和索引

时间:2009-01-20 18:28:00

标签: sql-server tsql indexing primary-key

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

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

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

11 个答案:

答案 0 :(得分:63)

你是对的,SQL Server允许你在同一个字段上创建重复索引,这让人很困惑。但是你可以创建另一个并不表明PK索引也不存在。

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

答案 1 :(得分:44)

正如其他人已经说过的那样,主键会自动编入索引。

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

例如,您有一个包含许多列的表,但您只查询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

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

答案 2 :(得分:27)

注意:此答案解决了企业级开发 in-the-large

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

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

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

基本问题是每行插入一行或更新主键列都会导致索引扫描以确保唯一性。随着表的增长,这种独特的索引扫描(或其在任何一个RDBMS中的等价物)变得更加昂贵,直到它占据了表的性能。

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

答案 3 :(得分:17)

默认情况下,主键始终为索引编制索引。

  

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

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

答案 4 :(得分:7)

除非您指定非群集

,否则PK将成为聚簇索引

答案 5 :(得分:7)

这里是MSDN

的段落
  

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

答案 6 :(得分:2)

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

答案 7 :(得分:1)

在SQL Server中,通常,主键会自动编入索引。 这是事实,但不保证更快的查询。 当只有一个字段作为主键时,主键将为您提供出色的性能。 但是,当有多个字段作为主键时,则索引基于这些字段。

例如: 字段A,B,C是主键,因此当您根据WHERE CLAUSE中的这3个字段进行查询时,性能良好, 但是当您想在WHERE CLAUSE中使用Only C字段进行查询时,您将无法获得良好的性能。因此,为了提高性能并运行,您需要手动索引C字段。

大多数时候,在你达到100多万条记录之前,你不会看到这个问题。

答案 8 :(得分:1)

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

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

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

  • 要创建具有相同名称的索引
  • 拒绝创建的索引作为约束,如果没有约束则不允许存在

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

因此,PRIMARY KEYUNIQUE INDEX之间是否存在实际差异:

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

答案 9 :(得分:0)

主键自动编入索引

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

  • index zip_code,如果您经常通过zip_code和id
  • 选择,则id可能会有所帮助

答案 10 :(得分:0)

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

每当我通过主键查询时,结果都是即时的。