代码之家  ›  专栏  ›  技术社区  ›  MichaelGG

uniqueidentifier pk:SQL Server堆是正确的选择吗?

  •  4
  • MichaelGG  · 技术社区  · 15 年前

    好啊。我经常读到关于SQL Server堆的一些东西,但是没有什么太明确的东西可以真正指导我。我将尝试衡量绩效,但希望对我应该调查的内容有一些指导。这是SQL Server 2008 Enterprise。以下是表格:

    乔布斯

    • 作业ID(pk,guid,外部生成)
    • 开始日期(日期时间2)
    • 记帐
    • 还有几个会计领域,主要是小数和大整数

    作业步骤

    • 作业步骤ID(pk,guid,外部生成)
    • 作业ID FK
    • 起始日期
    • 还有几个会计领域,主要是小数和大整数

    用法: 大量的插入(数百/秒),通常每个作业一个作业步骤。估计每月大约有100-200米行。完全没有更新,唯一删除的是存档超过3个月的数据。

    每秒对数据执行大约10次查询。有些人加入工作,有些人只是看工作。几乎所有查询都将在startdate范围内,其中大多数包括accountID和其他一些会计字段(我们对它们进行了索引)。查询非常简单——执行计划的最大部分是jobsteps的连接。

    优先级是插入性能。对于查询中出现的数据,有些延迟(大约5分钟)是可以容忍的,因此复制到其他服务器并从中运行查询当然是允许的。

    基于guid的查找非常罕见,除了将jobsteps连接到jobs之外。

    当前设置 :没有聚集索引。唯一一个看起来像候选人的是StartDate。但是,它并没有完全增加。作业可以在开始日期后的3小时窗口中的任意位置插入。这可能意味着以非最终顺序插入了一百万行。

    一个1作业+1作业stepid的数据大小,加上我当前的索引,大约是500字节。

    问题 :

    • 这是一个很好的使用堆吗?

    • 当startdate在大约2小时/100万行中几乎没有连续性时,集群对它有什么影响?我的猜测是不断的重新排序会杀死insert-perf。

    • 我应该只添加bigint-pk来拥有更小的、总是递增的密钥吗?(我仍然需要吉他来查找。)

    我读 GUIDs as PRIMARY KEYs and/or the clustering key 这似乎表明,即使是发明了一个键,也会在其他索引上节省相当大的空间。还有一些资源建议堆一般都有一些性能问题,但我不确定这是否仍然适用于SQL 2008。

    再次,是的,我将尝试进行测试和测量。我只是想得到一些指导或其他文章的链接,这样我就可以更明智地决定要考虑哪些途径。

    4 回复  |  直到 14 年前
        1
  •  5
  •   gbn    15 年前

    是的,堆有问题。您的数据将逻辑上碎片化整个节目,不能简单地进行碎片整理。

    想象一下,把你所有的电话簿扔进一个桶里,然后试图找到“鲍勃·史密斯”。或者使用传统的电话目录,在lastname、firstname上使用聚集索引。

    维护索引的开销很小。

    除非是唯一的,否则StartDate不是一个好的选择。聚集索引需要非聚集索引的内部唯一性。如果未声明唯一,SQL Server将添加一个4字节的“uniquifier”。

    是的,我会用int或bigint来简化。关于guid:请参见屏幕右侧的问题。

    编辑:

    注意,pk和聚集索引是两个独立的问题,即使默认情况下SQL Server会使pk聚集。

        2
  •  3
  •   Rob Farley    15 年前

    堆碎片化不一定是世界末日。听起来你很少扫描数据,所以这不是世界末日。

    非聚集索引会影响性能。每一个都需要将行的地址存储在underlynig表(堆或聚集索引)中。理想情况下,查询不必使用基础表本身,因为它以理想的方式存储所需的所有信息(包括所有列,因此它是一个覆盖索引)。

    是的,金伯利·特里普的东西是指数的最佳选择。

    罗布

        3
  •  2
  •   marc_s    15 年前

    正如您自己的研究所显示的,以及所有其他应答者所提到的,使用guid作为表上的聚集索引是一个坏主意。

    然而,拥有一个堆也不是一个很好的选择,因为堆还有其他问题,主要是与碎片和其他不适合堆的事情有关。

    我的最佳实践建议是:

    • 在任何数据表上都要使用主聚集键(除非它是临时表或用于大容量加载的表)
    • 尝试确保聚集键是int标识或bigint标识

    我认为,通过添加int/bigint(即使只是为了拥有一个好的聚集索引)所获得的好处远远超过了它的缺点(正如KimTripp在她的博客文章中提到的那样)。

    马克

        4
  •  1
  •   Robin Day    15 年前

    由于guid是您的主键和外键,您的数据库仍然需要检查每个插入的约束,您可能需要对其进行索引。索引一个guid是不可取的,因为它是随机的。因此,我认为绝对应该沿着主密钥的bigint(可能是标识)路径走,并将其用作聚集索引。