sql服务器中书签查找的性能损失

在我的博客里,我曾经在SQL Serverl关于书签查找的谈话,和许多他们所带来的问题,在今天的文章中,我想进一步谈谈书签查找从性能的角度来看,他们如何能降低你的整个SQL服务器的性能。

书签查找-重复循环

如果您的非聚集索引不是覆盖非聚集索引,则SQLServer的查询优化器将引入书签查找。对于从非聚集索引返回的每一行,SQLServer需要在聚合索引或堆形式中执行额外的查找操作。

例如,当你的聚集索引包含3层,为了返回必要的信息,每一行,你需要阅读3页。因此,查询优化器选择书签查找操作的执行计划,只有当它是有意义的-根据你查询的选择。下图显示一个书签查找操作的执行计划。


通常,人们很少注意书签查找,因为它们只执行几次,如果查询选择太低,查询优化器将直接使用聚合索引扫描或表扫描操作符扫描整个表,但我们只使用SQL Server重用缓存的执行计划。这个计划有许多不同的运行值,包括书签查找(基于初始输入值),所以这很容易发生,并且书签查找是反复执行的。

为了演示这个性能问题,下一个查询指定查询优化器使用一个特定的非聚集索引。查询本身返回80000行,因为对于每个查询执行,SQL Server需要一个书签查找80000次重复执行。


创建程序检索数据
作为
SELECT * FROM表与(指数(idxtable1_column2))
这里的位置= 2



下图显示了查询执行后的实际执行计划。


执行计划看起来很糟糕(查询优化器甚至启用了并行计划!)因为书签查找操作符在这里执行了80000次,所以查询本身产生了165000多个逻辑读取!(逻辑读的数目可以从统计IO获得)。


接下来,让我们来告诉你会发生什么时,你有许多平行的SQL Server用户执行这个糟糕的查询。我会用ostress.exe(RML工具的一部分)来模拟100个并行用户查询。

ostress.exe - qexec bookmarklookupsperformance.dbo.retrievedata -N100 Q

我花了将近15秒在我的测试系统上完成100个并行查询,在此期间CPU非常高,因为SQL Server需要一个嵌套循环操作符来进行书签查找操作,当然,嵌套循环操作占CPU资源的一部分。

现在让我们修改索引设计来创建这个查询的非聚合索引的覆盖率。如果使用非聚合索引,查询优化器不需要再次在计划中执行书签查找:


在表创建聚集索引idxtable1_column2(的位置)
INCLUDE (Column2)
与(drop_existing =对)



这一次,当我们执行相同的查询ostress.exe再一次,我们看到,每一个查询在5秒内完成。来自15秒我们刚才看到的非常不同。这是覆盖非聚集索引的力量。在查询中,可以直接在非聚集索引中找到阀门请求的数据,避免了书签查找。

总结

在这篇文章中我给你一个坏的书签查找会伤害性能。因此,它是非常重要的快速完成查询的重要查询使用并行书签查找的执行计划是不是一个好的选择,非聚集索引的覆盖,这里可以帮助你。这种方法可以在下次考虑设计指标。

以上是本文的全部内容,希望本文的内容能给大家的学习或工作带来一定的帮助,同时也希望能给予更多的支持!