Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.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旧版数据库是否为聚集索引_Sql_Sql Server_Indexing_Clustered Index_Identity Column - Fatal编程技术网

Sql Server旧版数据库是否为聚集索引

Sql Server旧版数据库是否为聚集索引,sql,sql-server,indexing,clustered-index,identity-column,Sql,Sql Server,Indexing,Clustered Index,Identity Column,我们有一个遗留数据库,它是SQLServerDB(2005年和2008年) 表中的所有主键都是唯一标识符 这些表目前没有在其上创建聚集索引,我们在只有750k条记录的表上遇到了性能问题。这是我使用唯一标识符作为唯一主键处理的第一个数据库,我从未见过sql server返回数据的速度如此之慢 我不想在uniqueidentifier上创建聚集索引,因为它们不是连续的,因此在插入数据时会减慢应用程序的速度 我们无法删除用于远程站点记录标识管理目的的uniqueidentifier 我曾考虑过向表中添

我们有一个遗留数据库,它是SQLServerDB(2005年和2008年)

表中的所有主键都是唯一标识符

这些表目前没有在其上创建聚集索引,我们在只有750k条记录的表上遇到了性能问题。这是我使用唯一标识符作为唯一主键处理的第一个数据库,我从未见过sql server返回数据的速度如此之慢

我不想在uniqueidentifier上创建聚集索引,因为它们不是连续的,因此在插入数据时会减慢应用程序的速度

我们无法删除用于远程站点记录标识管理目的的uniqueidentifier

我曾考虑过向表中添加一个大整数标识列,并在该列上创建聚集索引,包括惟一标识符列

i、 e

int identity-保持插入速度的第一列 唯一标识符-确保应用程序按预期工作

目标是提高标识查询和联接表查询的性能

问题1:这会提高数据库的查询性能还是会降低查询速度

问题2:有没有我没有列出的替代方案

谢谢 皮特

Edit:性能问题在于通过select语句快速检索数据,特别是在将一些更“事务性/更改性”的表连接在一起时

编辑2:表之间的连接通常都在主键和外键之间,对于具有外键的表,它们被包括在非聚集索引中,以提供更具覆盖性的索引

所有这些表都没有其他值可以提供良好的聚集索引

我更倾向于在每个高负载表上添加一个额外的标识列,然后在聚集索引中包含当前的Guid PK列,以提供最佳的查询性能

编辑3: 我估计80%的查询是通过数据访问机制仅对主键和外键执行的。通常,我们的数据模型具有延迟加载的对象,这些对象在访问时执行查询,这些查询使用对象id和PK列。我们有大量用户驱动的数据排除/包含查询,这些查询使用外键列作为基于类型X排除以下id的条件的过滤器。剩下的20%是关于枚举(int)或日期范围列的where子句,系统中很少执行基于文本的查询


在可能的情况下,我已经添加了覆盖索引来覆盖最重的查询,但到目前为止,我仍然对性能感到失望。正如bluefooted所说,数据是以堆的形式存储的。

我不确定您的GUI来自何处,但如果它们是在插入过程中生成的,那么使用SQL Server中的而不是将有助于您避免插入过程中的碎片问题

关于聚集索引的选择,正如Kimberly L.Tripp所说:“选择聚集索引的最重要因素是它的唯一性、狭窄性和静态性(不断增加的值对最小化拆分有其他好处)。”与INT甚至BIGINT相比,GUID不符合狭窄的要求


Kimberly也有一篇关于的优秀文章。

您没有指出您的性能问题是什么。如果执行最差的操作是插入,那么您的解决方案可能是正确的。如果是其他原因,那么我会看看聚集索引如何帮助实现这一点


您可以查看表上的现有索引以及使用它们的查询。您可以选择一个索引,该索引虽然稍微降低了插入,但对当前的性能问题区域提供了更大的好处。

如果表上没有聚集索引,它将存储为堆而不是b树。在SQL Server中,堆数据访问是非常糟糕的,所以您肯定需要添加聚集索引

我同意您的分析,即GUID列对于集群来说是一个糟糕的选择,特别是因为您没有能力使用NEWSEQUENTIALID()。如果愿意,您可以创建一个新的人工整数键,但如果有另一列或列的组合可以作为聚集索引使用,也可以


您是否有经常用于范围扫描的字段?哪些列用于联接?除了GUID之外,是否还有唯一标识行的列组合?发布数据模型的示例将有助于我们推荐一个很好的集群候选对象。

我还不是100%清楚:您的第一号访问模式是按GUID还是按其他列查询表?当连接到其他表时,最常用的列(和数据类型)是什么

在我进一步了解如何使用这些guid之前,我无法给出任何可靠的建议。我知道您说过它们是主键,但这并不保证它们被用作查询或连接的主要条件

更新

现在我知道多一点,我有一个疯狂的建议。在guid上对这些表进行集群,但将填充因子设置为60%。这将改善页面分割问题,并在查询这些小狗时提供更好的性能

至于使用Guid.NewGuid(),看来您毕竟可以在C#中使用顺序Guid。我在此处找到以下代码,因此:

[DllImport("rpcrt4.dll", SetLastError = true)]
static extern int UuidCreateSequential(out Guid guid);

public static Guid SequentialGuid()
{
    const int RPC_S_OK = 0;
    Guid g;
    if (UuidCreateSequential(out g) != RPC_S_OK)
        return Guid.NewGuid();
    else
        return g;
}

newsequentialID()实际上只是UuidCreateSequential的包装器。我确信,如果您不能直接在客户端上使用它,您可以找到一种方法,快速往返到服务器,从那里获取一个新的顺序id,甚至可以使用一个“分发器”表和一个存储过程来完成这项工作。

您当前在uniqueidentifiers上有一个非聚集索引吗?是的,我们有非聚集索引