Sql 添加主键是否会导致基础数据的重组

Sql 添加主键是否会导致基础数据的重组,sql,sql-server,sql-server-2008,primary-key,clustered-index,Sql,Sql Server,Sql Server 2008,Primary Key,Clustered Index,我正在将大量数据导入SQL Server数据库。源数据来自PgSql,包括表def,我通过一些相当简单的正则表达式将其转换为TSql。这将创建没有主键的表 据我所知,缺少主键/集群索引意味着数据存储在堆中 导入完成后,我将添加PKs,如下所示: ALTER TABLE someTable ADD CONSTRAINT PK_someTable PRIMARY KEY (id); ALTER TABLE someTable ADD CONSTRAINT PK_someTable PRIMARY

我正在将大量数据导入SQL Server数据库。源数据来自PgSql,包括表def,我通过一些相当简单的正则表达式将其转换为TSql。这将创建没有主键的表

据我所知,缺少主键/集群索引意味着数据存储在堆中

导入完成后,我将添加PKs,如下所示:

ALTER TABLE someTable ADD CONSTRAINT PK_someTable PRIMARY KEY (id);
ALTER TABLE someTable ADD CONSTRAINT PK_someTable PRIMARY KEY CLUSTERED (id);
注意缺少集群关键字。现在怎么了?还是一堆?主键对查找有什么影响?这与添加标准索引真的有什么不同吗

现在,假设我添加PKs,如下所示:

ALTER TABLE someTable ADD CONSTRAINT PK_someTable PRIMARY KEY (id);
ALTER TABLE someTable ADD CONSTRAINT PK_someTable PRIMARY KEY CLUSTERED (id);
我假设这现在完全将表重新构造为基于行的结构,通过PK进行更高效的查找,但插入特性不太理想

我的假设正确吗

如果我的导入按主键顺序插入数据,那么首先省略主键有什么好处吗?

执行时

ALTER TABLE someTable ADD CONSTRAINT PK_someTable PRIMARY KEY (id);
如果someTable上没有聚集索引,则PK将是聚集PK。否则,如果在执行ALTER.之前存在聚集索引。。添加主键id主键将是非群集主键

-测试1

-测试2

当你执行

ALTER TABLE someTable ADD CONSTRAINT PK_someTable PRIMARY KEY (id);
如果someTable上没有聚集索引,则PK将是聚集PK。否则,如果在执行ALTER.之前存在聚集索引。。添加主键id主键将是非群集主键

-测试1

-测试2


在sql server中,如果不存在聚集索引,则主键默认为聚集索引。聚集索引实际上意味着索引不像非聚集索引那样保存在单独的存储区域中,而是索引数据散布在相应的常规表数据中。如果你想了解这一点,你会发现它们只能是1个集群索引

聚集索引的真正优点是数据靠近索引数据,因此当驱动器头位于该区域时,您可以同时获取这两个数据。当处理的数据显示出引用的局部性时,聚集索引的速度明显快于非聚集索引——当几乎相同值的行倾向于同时读取时

例如,如果您的主键是SSN,那么您不会获得很大的优势,除非您处理的数据是相对于SSN随机排序的——尽管由于数据的接近,您确实会获得优势。但是,如果可以通过SSN对输入进行预排序,那么集群密钥是一个很大的优势


因此,是的,聚集索引确实会对数据进行重新排序,使其与聚集索引混合。

在sql server中,如果不存在聚集索引,则主键默认为聚集。聚集索引实际上意味着索引不像非聚集索引那样保存在单独的存储区域中,而是索引数据散布在相应的常规表数据中。如果你想了解这一点,你会发现它们只能是1个集群索引

聚集索引的真正优点是数据靠近索引数据,因此当驱动器头位于该区域时,您可以同时获取这两个数据。当处理的数据显示出引用的局部性时,聚集索引的速度明显快于非聚集索引——当几乎相同值的行倾向于同时读取时

例如,如果您的主键是SSN,那么您不会获得很大的优势,除非您处理的数据是相对于SSN随机排序的——尽管由于数据的接近,您确实会获得优势。但是,如果可以通过SSN对输入进行预排序,那么集群密钥是一个很大的优势


是的,聚集索引确实会对数据进行重新排序,使其与聚集索引混合。

感谢您对主题的精彩演示

上面的结论并没有错,但它显示了索引的结构,而不是表格的结构。我认为以下SQL将显示实际表的信息:

select 
    o.name, 
    o.object_id, 
    case 
      when p.index_id = 0 then 'Heap'
      when p.index_id = 1 then 'Clustered Index/b-tree'
      when p.index_id > 1 then 'Non-clustered Index/b-tree'
    end as 'Type'
from sys.objects o
inner join sys.partitions p on p.object_id = o.object_id
where o.name = 'MyTable';
您将看到MyTable是集群的:

name    object_id   Type
------- ----------- -------------------
MyTable 1237579447  Clustered Index/b-tree

感谢您对本主题的精彩演示

上面的结论并没有错,但它显示了索引的结构,而不是表格的结构。我认为以下SQL将显示实际表的信息:

select 
    o.name, 
    o.object_id, 
    case 
      when p.index_id = 0 then 'Heap'
      when p.index_id = 1 then 'Clustered Index/b-tree'
      when p.index_id > 1 then 'Non-clustered Index/b-tree'
    end as 'Type'
from sys.objects o
inner join sys.partitions p on p.object_id = o.object_id
where o.name = 'MyTable';
您将看到MyTable是集群的:

name    object_id   Type
------- ----------- -------------------
MyTable 1237579447  Clustered Index/b-tree

回答得很好。如果可以的话,我愿意+2。Thx.对我上一期有什么想法吗?很好的回答。如果可以的话,我愿意+2。Thx.关于我的上一个问题有什么想法吗?你想插入行,然后添加PK吗?我可以这样做,但考虑到数据量,我宁愿了解发生了什么,也不愿花5-8个小时测试不同的场景。我可以在之前或之后添加键,但插入将按主键顺序进行。如果目标表是堆,则插入应该更快。但是,对于具有PK非集群的堆表,其整体insert、update、delete、select性能应该比集群表的性能差。看看这个。
如果你导入了大量数据,你应该看一看。也可以看到这个。你想插入行,然后添加PK吗?我也可以这样做,但考虑到数据量,我宁愿了解发生了什么,也不愿花5-8个小时测试不同的场景。我可以在之前或之后添加键,但插入将按主键顺序进行。如果目标表是堆,则插入应该更快。但是,对于具有PK非集群的堆表,其整体insert、update、delete、select性能应该比集群表的性能差。看看这个。如果你导入了大量的数据,你应该看一下。也可以看到这个。由于数据库是多用户的,事情从来不像我说的那么简单。但是,在处理发票之类的事情时,如果发票项将发票编号作为客户索引的一部分,则一次获取所有行项目的速度通常会快得多。由于数据库是多用户的,所以事情从来不像我说的那么简单。但是,在处理发票之类的事情时,如果发票项将发票编号作为客户索引的一部分,则在一次获取所有行项目通常会快得多。