Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 2005 SQL 2005中表上主键和聚集索引的智能选择,可提高选择单个记录或多个记录的性能_Sql Server 2005_Performance_Primary Key_Clustered Index - Fatal编程技术网

Sql server 2005 SQL 2005中表上主键和聚集索引的智能选择,可提高选择单个记录或多个记录的性能

Sql server 2005 SQL 2005中表上主键和聚集索引的智能选择,可提高选择单个记录或多个记录的性能,sql-server-2005,performance,primary-key,clustered-index,Sql Server 2005,Performance,Primary Key,Clustered Index,编辑:我添加了“Slug”列,以解决特定记录选择的性能问题 我的表中有以下列 Id Int - Primary key (identity, clustered by default) Slug varchar(100) ... EntryDate DateTime 大多数情况下,我会按EntryDate排序select语句,如下所示 Select T.Id, T.Slug, ..., T.EntryDate From ( Select Id, Slug, ..., EntryDate

编辑:我添加了“Slug”列,以解决特定记录选择的性能问题

我的表中有以下列

Id Int - Primary key (identity, clustered by default)
Slug varchar(100)
...
EntryDate DateTime
大多数情况下,我会按EntryDate排序select语句,如下所示

Select T.Id, T.Slug, ..., T.EntryDate
From (
    Select Id, Slug, ..., EntryDate,  
        Row_Number() Over (Order By EntryDate Desc, Id Desc) AS RowNum
    From TableName
    Where ...
) As T
Where T.RowNum Between ... And ...
我按EntryDate和Id订购,以防有重复的EntryDates

当我选择一条记录时,我会执行以下操作

Select Id, Slug, ..., EntryDate
From TableName
Where Slug = @slug And Year(EntryDate) = @entryYear 
    And Month(EntryDate) = @entryMonth
我有一个独特的Slug&EntryDate键

在我的情况下,什么是键和索引的明智选择?我面临性能问题,可能是因为我是按一个没有聚集索引的列排序的

我应该将Id设置为非聚集主键,将EntryDate设置为聚集索引吗

我感谢你的帮助。谢谢

编辑:


我还没有尝试在EntryDate上添加非聚集索引。从后端插入数据,所以插入的性能对我来说不是什么大问题。此外,EntryDate并不总是插入时的日期。这可能是一个过去的日期。后端用户选择日期。

您是否尝试过简单地在entrydate上添加一个非聚集索引,以查看您获得了什么样的性能提升


此外,多久添加一次新数据?添加的新数据是否总是>=最后一个EntryDate?

您是否尝试过在EntryDate上添加一个非聚集索引,以查看您获得了什么样的性能提升


此外,多久添加一次新数据?添加的新数据是否总是>=最后一个EntryDate?

您希望将ID保留为聚集索引,因为您很可能会根据ID而不是输入日期加入表


只有日期字段的简单非聚集索引可以加快速度。

您希望将ID保留为聚集索引,因为您很可能会通过ID而不是输入日期加入表

只有日期字段的简单非聚集索引可以加快速度。

聚集有点像“索引分页”,索引是“分块”的,而不仅仅是一个长列表。当您拥有大量数据时,这会很有帮助。DB可以在集群范围内搜索,然后查找单个记录。它使索引更小,因此搜索速度更快,但不太具体。一旦在集群中找到正确的位置,它就需要在集群中搜索

使用大量数据时速度更快,但使用较小的数据集时速度较慢

如果没有使用主键进行大量搜索,则对日期进行聚类,并将主键保留为非聚类。这实际上取决于您的查询在连接其他表时有多复杂。

集群有点像“索引分页”,索引是“分块的”,而不仅仅是一个长列表。当您拥有大量数据时,这会很有帮助。DB可以在集群范围内搜索,然后查找单个记录。它使索引更小,因此搜索速度更快,但不太具体。一旦在集群中找到正确的位置,它就需要在集群中搜索

使用大量数据时速度更快,但使用较小的数据集时速度较慢


如果没有使用主键进行大量搜索,则对日期进行聚类,并将主键保留为非聚类。这实际上取决于您的查询在连接其他表时有多复杂。

根据当前的表布局,您需要这样的索引

CREATE INDEX IX_YourTable_1 ON dbo.YourTable
(EntryDate, Id)
INCLUDE (SLug)
WITH (FILLFACTOR=90)

CREATE INDEX IX_YourTable_2 ON dbo.YourTable
(EntryDate, Slug)
INCLUDE (Id)
WITH (FILLFACTOR=80)
Select Id, Slug, ..., EntryDate
From TableName
Where Slug = @slug 
    AND EntryDate BETWEEN CAST(CAST(@EntryYear AS VARCHAR(4) + CAST(@EntryMonth AS VARCHAR(2)) + '01' AS DATE) AND DATEADD(mm, 1, CAST(CAST(@EntryYear AS VARCHAR(4) + CAST(@EntryMonth AS VARCHAR(2)) + '01' AS DATE))
添加要返回到包含行的任何其他列

将第二个查询更改为类似以下内容

CREATE INDEX IX_YourTable_1 ON dbo.YourTable
(EntryDate, Id)
INCLUDE (SLug)
WITH (FILLFACTOR=90)

CREATE INDEX IX_YourTable_2 ON dbo.YourTable
(EntryDate, Slug)
INCLUDE (Id)
WITH (FILLFACTOR=80)
Select Id, Slug, ..., EntryDate
From TableName
Where Slug = @slug 
    AND EntryDate BETWEEN CAST(CAST(@EntryYear AS VARCHAR(4) + CAST(@EntryMonth AS VARCHAR(2)) + '01' AS DATE) AND DATEADD(mm, 1, CAST(CAST(@EntryYear AS VARCHAR(4) + CAST(@EntryMonth AS VARCHAR(2)) + '01' AS DATE))

当前编写第二个查询的方式永远不会使用索引。如果可以将Slug列更改为相关表,则会提高性能并降低存储要求。

根据当前的表布局,您需要一些如下索引

CREATE INDEX IX_YourTable_1 ON dbo.YourTable
(EntryDate, Id)
INCLUDE (SLug)
WITH (FILLFACTOR=90)

CREATE INDEX IX_YourTable_2 ON dbo.YourTable
(EntryDate, Slug)
INCLUDE (Id)
WITH (FILLFACTOR=80)
Select Id, Slug, ..., EntryDate
From TableName
Where Slug = @slug 
    AND EntryDate BETWEEN CAST(CAST(@EntryYear AS VARCHAR(4) + CAST(@EntryMonth AS VARCHAR(2)) + '01' AS DATE) AND DATEADD(mm, 1, CAST(CAST(@EntryYear AS VARCHAR(4) + CAST(@EntryMonth AS VARCHAR(2)) + '01' AS DATE))
添加要返回到包含行的任何其他列

将第二个查询更改为类似以下内容

CREATE INDEX IX_YourTable_1 ON dbo.YourTable
(EntryDate, Id)
INCLUDE (SLug)
WITH (FILLFACTOR=90)

CREATE INDEX IX_YourTable_2 ON dbo.YourTable
(EntryDate, Slug)
INCLUDE (Id)
WITH (FILLFACTOR=80)
Select Id, Slug, ..., EntryDate
From TableName
Where Slug = @slug 
    AND EntryDate BETWEEN CAST(CAST(@EntryYear AS VARCHAR(4) + CAST(@EntryMonth AS VARCHAR(2)) + '01' AS DATE) AND DATEADD(mm, 1, CAST(CAST(@EntryYear AS VARCHAR(4) + CAST(@EntryMonth AS VARCHAR(2)) + '01' AS DATE))

当前编写第二个查询的方式永远不会使用索引。如果可以将Slug列更改为相关表,则会提高性能并降低存储要求。

如果返回一组记录,并且返回的某些字段不是索引的一部分,则聚集索引只会产生任何影响。否则就没有好处了

您首先需要了解查询计划告诉您当前查询速度慢的原因。如果没有这一点,大部分都是空泛的猜测(这在优化查询时通常会适得其反)


如果没有一个可靠的查询计划来比较,我不会尝试任何事情(由我或其他人建议),至少要知道你做的是好事还是坏事。

如果你返回一堆记录,并且返回的某些字段不是索引的一部分,聚集索引只会产生任何影响。否则就没有好处了

您首先需要了解查询计划告诉您当前查询速度慢的原因。如果没有这一点,大部分都是空泛的猜测(这在优化查询时通常会适得其反)


如果没有一个可靠的查询计划可供比较,我不会尝试任何事情(由我或其他人建议),至少要知道你做的是好事还是坏事。

不,我没有尝试在EntryDate上添加非聚集索引。从后端插入数据,所以插入的性能对我来说不是什么大问题。此外,EntryDate并不总是插入时的日期。这可能是一个过去的日期。后端用户选择日期。不,我没有尝试在EntryDate上添加非聚集索引。从后端插入数据,所以插入的性能对我来说不是什么大问题。此外,EntryDate并不总是插入时的日期。这可能是一个过去的日期。后端用户选择日期。我在示例中添加了“Slug”列,以解决选择单个特定记录时的性能问题。你能看一下吗?谢谢,会的