在uniqueidentifier列上具有唯一约束的性能影响?

时间:2018-04-20 13:00:07

标签: sql sql-server indexing uniqueidentifier

在uniqueidentifier(即真实随机标识符)列上创建非聚簇索引会导致碎片索引,从而影响性能。

在SQL Server上,创建唯一约束是the same as,创建唯一索引。

代码示例

在这种情况下,我有来自客户端应用程序的事件。在某些情况下,这些客户端应用程序可以多次发送相同的事件,并且我要求不保存两次保存事件。

我对聚集索引使用--[PersonnelID is null if ProductDPA =5] SELECT dbo.OrganisationPersonnel.OrganisationID , null AS PersonnelID -- PersonnelID is null if ProductDPA =5 , dbo.Title.Name , dbo.Person.FirstName , dbo.Person.MiddleName , dbo.Person.LastName , dbo.OrganisationPersonnel.ActualJobTitle , dbo.Phone.Number , dbo.Email.Email , dbo.Person.ProductDPAID , dbo.ProductDPA.Name FROM dbo.OrganisationPersonnel INNER JOIN dbo.Person ON dbo.OrganisationPersonnel.PersonnelID = dbo.Person.ID INNER JOIN dbo.Title ON dbo.Person.TitleID = dbo.Title.ID LEFT JOIN dbo.Phone ON dbo.OrganisationPersonnel.PhoneID = dbo.Phone.ID LEFT JOIN dbo.Email ON dbo.OrganisationPersonnel.EmailID = dbo.Email.ID INNER JOIN dbo.ProductDPA ON dbo.Person.ProductDPAID = dbo.ProductDPA.ID WHERE dbo.Person.ProductDPAID = 5 --All ProductDPA =5 & All EmployedToDate Is Null or dbo.OrganisationPersonnel.EmployedToDate Is Null union all --Phone Number is null if ProductDPA = 2 SELECT dbo.OrganisationPersonnel.OrganisationID , OrganisationPersonnel.PersonnelID , dbo.Title.Name , dbo.Person.FirstName , dbo.Person.MiddleName , dbo.Person.LastName , dbo.OrganisationPersonnel.ActualJobTitle , null as Number --Phone Number is null if ProductDPA = 2 , dbo.Email.Email , dbo.Person.ProductDPAID , dbo.ProductDPA.Name FROM dbo.OrganisationPersonnel INNER JOIN dbo.Person ON dbo.OrganisationPersonnel.PersonnelID = dbo.Person.ID INNER JOIN dbo.Title ON dbo.Person.TitleID = dbo.Title.ID LEFT JOIN dbo.Phone ON dbo.OrganisationPersonnel.PhoneID = dbo.Phone.ID LEFT JOIN dbo.Email ON dbo.OrganisationPersonnel.EmailID = dbo.Email.ID INNER JOIN dbo.ProductDPA ON dbo.Person.ProductDPAID = dbo.ProductDPA.ID WHERE ProductDPAID in (2) --Phone Number is null if ProductDPA = 2 union all --Email is null if ProductDPA =3 SELECT dbo.OrganisationPersonnel.OrganisationID , OrganisationPersonnel.PersonnelID , dbo.Title.Name , dbo.Person.FirstName , dbo.Person.MiddleName , dbo.Person.LastName , dbo.OrganisationPersonnel.ActualJobTitle , dbo.Phone.Number , null AS Email --Email is null if ProductDPA =3 , dbo.Person.ProductDPAID , dbo.ProductDPA.Name FROM dbo.OrganisationPersonnel INNER JOIN dbo.Person ON dbo.OrganisationPersonnel.PersonnelID = dbo.Person.ID INNER JOIN dbo.Title ON dbo.Person.TitleID = dbo.Title.ID LEFT JOIN dbo.Phone ON dbo.OrganisationPersonnel.PhoneID = dbo.Phone.ID LEFT JOIN dbo.Email ON dbo.OrganisationPersonnel.EmailID = dbo.Email.ID INNER JOIN dbo.ProductDPA ON dbo.Person.ProductDPAID = dbo.ProductDPA.ID WHERE ProductDPAID in (3) --Email is null if ProductDPA =3 union all --Phone Number and Email is null if ProductDPA = 4 SELECT dbo.OrganisationPersonnel.OrganisationID , OrganisationPersonnel.PersonnelID , dbo.Title.Name , dbo.Person.FirstName , dbo.Person.MiddleName , dbo.Person.LastName , dbo.OrganisationPersonnel.ActualJobTitle , null as Number , null AS Email , dbo.Person.ProductDPAID , dbo.ProductDPA.Name FROM dbo.OrganisationPersonnel INNER JOIN dbo.Person ON dbo.OrganisationPersonnel.PersonnelID = dbo.Person.ID INNER JOIN dbo.Title ON dbo.Person.TitleID = dbo.Title.ID LEFT JOIN dbo.Phone ON dbo.OrganisationPersonnel.PhoneID = dbo.Phone.ID LEFT JOIN dbo.Email ON dbo.OrganisationPersonnel.EmailID = dbo.Email.ID INNER JOIN dbo.ProductDPA ON dbo.Person.ProductDPAID = dbo.ProductDPA.ID WHERE ProductDPAID in (4) --Email is null if ProductDPA = 4 ORDER BY dbo.OrganisationPersonnel.OrganisationID; 列,并将表中事件的ID保留为唯一约束。这是一个例子:

int

问题

uniqueidentifier上的唯一约束(即uniqueidentifier的底层索引)是否会影响表的性能?

3 个答案:

答案 0 :(得分:2)

任何索引,主键或唯一约束都会受到一些性能影响。权衡取舍是针对略微且通常可忽略不计的写入性能的更高检索性能。

要编制索引的键或值的大小也会影响性能。 UNIQUEIDENTIFIER是128位值,BIGINT是64位,INT是32位。索引VARCHAR或CHAR字段将反映该数据类型的大小。

使用UNIQUEIDENTIFIER,您可以从称为页面拆分的内容中遇到性能命中。一个页面是8K,可以容纳8K的记录数。如果您需要添加一个位于整页中间的新记录,那么现有页面必须创建两个新页面,以保存每个页面中原始数据的一半加上您的新记录指针。这在聚簇索引中特别痛苦,因为聚簇索引会影响记录的物理存储。

页面拆分是使用UNIQUEIDENTIFIER数据类型的一个不可避免的部分,这些数据类型通过将它们放在聚簇键中而加剧。我建议您不要在这些数据类型上使用群集密钥。

UNIQUEIDENTIFIER数据类型(除了唯一性)的好处是它们的随机特性可以防止数据页中的热点。

在您的示例中,您同时具有INT标识字段和具有NewID()默认值的UNIQUEIDENTIFIER。如果这不仅仅是一个例子,我应该好奇为什么你们两个都有?

答案 1 :(得分:1)

这个link有点老了,但它基本上回答了你的问题......"从性能的角度来看,UNIQUE约束和唯一索引实际上与查询优化器相同,你不会看到使用一个与另一个相比的任何性能优势。"

答案 2 :(得分:0)

任何索引都有一些写入操作的开销。索引也具有读取值。

如果您需要唯一值,[EventId]的搜索速度应远远超过维护和索引的成本。如果没有UNIQUE,则数据库不会强制执行唯一性,并且搜索退出的值将是表扫描。

您可以使用小于100的填充来减少碎片。

newsequentialid的默认值也会减少碎片。