在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的底层索引)是否会影响表的性能?
答案 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的默认值也会减少碎片。