我正在使用SQL Server,并且一直在仔细研究关键查找的概念,

http://blog.sqlauthority.com/2009/10/07/sql-server-query-query-optimization-remove-bookmark-bookmark-lookup-nokup-remove-remove-rid-lood-lookup-nookup-nekey-key-key-key-lookup/

因此,如果您有一个钥匙查找,则可以使用“ Include”列创建索引,以涵盖Select语句中您拥有的非索引列。

例如,

SELECT ID, FirstName FROM OneIndex WHERE City = 'Las Vegas'
GO

该索引将包括一个密钥查找,

CREATE NONCLUSTERED INDEX [IX_OneIndex_City] ON [dbo].[OneIndex]
(
[City] ASC
) ON [PRIMARY]
GO

但这将删除钥匙查找,

CREATE NONCLUSTERED INDEX [IX_OneIndex_Include] ON [dbo].[OneIndex]
(
City
) INCLUDE (FirstName,ID) ON [PRIMARY]
GO

我的意思是,这将对性能产生多少影响?主要查找的运营商成本为0.295969(99%),但这是什么意思?

您怎么知道您需要那里的第二个索引,在什么时候您试图添加太多索引,这是不值得的?

在我看来,有些查询可以包括索引扫描,关键查找,并且似乎仍然非常快。

有帮助吗?

解决方案

想象一下电话公司有电话号码列表,包括客户是谁,他们的住所,他们的计费号码等等。主要键可能是电话号码。

他们给你白页。这就像一个非群集索引,按名称排序,包括地址之类的列。

如果您想在书中找到所有的法利,并且对它们的地址感兴趣,那么您需要的是白页。您可以快速寻求Farleys(找到FS,等等),然后您拥有所需的所有信息。

但是,如果您想要他们的计费号码,那么您需要进行查找。您可以快速找到Farleys的所有电话号码,但是然后您需要将它们中的每个电话(数百)拿走,然后在主(群集)索引中进行另一个搜索(查找),该索引是由电话号码订购的。这些中的每一个大致与寻求找到法利的成本大致相同,这使您的查询运行数量更糟。

还有一个门槛。在某个时候,数据库将意识到,仅通过群集索引的每一页,检查每个记录以查看是否感兴趣,它会更快。

认真 - 摆脱查找。您的查询现在可能很快,但可能不会扩展。

其他提示

背景

在里面 最坏的情况下, ,包含查找的查询必须转到需要列数据的行的物理存储,该行未列出索引。在里面 很糟糕 在最坏的情况下,每个查找将需要单独的I/O,并且执行将必须等待该行的价值才能返回,然后再进行操作。如果查找必须处理A 重要的 行数。

这就是为什么查找如此糟糕的新闻界的原因。另一方面,请考虑在SQL Server 2000中引入查找功能。在SQL Server 7.0中,查询处理器只能使用非集群索引,如果包含索引 全部 满足查询所需的信息;在所有其他情况下,它都必须通过聚类索引访问数据(如果存在,则否则会扫描)。如果查找总是非常糟糕,那么SQL Server肯定不会介绍它们。

然后,在SQL Server 2000+中,我们有一个非集群索引,该索引提供有用的订购和/或查询所需的列,以及查找数的数量可能相对较小,使用非集群索引并执行执行一个 数量有限 基础表上的查找可能是最便宜的可用访问方法(尽管当然,完全覆盖的非集群索引可能仍然更便宜)。

在许多情况下,只是 不实用 要创建尽可能多的非集群索引,以免扫描所有常见查询。原因之一可能是 INSERT/UPDATE/DELETE/MERGE 性能比查询速度更重要(请记住,数据修改操作还必须维护所有受影响的非集群索引)。另一个原因可能是空间。每个非集群索引代表基本表(或其中表达式)列的子集的副本,只是对分类的分类方式有所不同。数据的更多副本意味着更多的存储空间,以及在SQL Server的内存数据缓存中争夺空间的更多内容。

其他时候,我们只能创建一些额外的索引(也许在SQL Server 2008+中过滤) INCLUDE 列以满足绝大多数性能至关重要的查询,而不会过多地损害数据修改性能,并且不使用太多额外的磁盘空间。平衡竞争考虑因素是使索引调整比科学更多的艺术。

成本

您问查找操作员的99%成本 方法 在查询计划中。查询优化器的成本成分产生 估计的 该操作的成本是总计的99% 估计的 对于查询。数字本身(0.29)根本没有太多的意义;出于所有实际目的,在比较该特定查询的替代策略时,您应该将其视为由优化器内部使用的无单位数字。

估计的成本不考虑您的硬件,配置,应用程序需求或其他任何内容。优化器使用的成本模型包括大量的启发式方法和简化的假设 发生 在大多数查询中,大多数情况下,在大多数硬件上都会制定合理的计划。这并不是说有 高成本运营商在计划和绩效方面之间的相关性;相反,链接通常比通常预期的要弱得多。一定要首先检查高估计成本计划运营商的原因,但不要将信息视为一个可能有缺陷的估计值以外的任何内容。

影响

我还想提及一些可以改善查找影响的因素。首先,我一开始就提到最坏的情况涉及 逐行物理I/O. 。如果满足查找所需的数据页(群集索引或堆)已经在内存中(数据缓存),则显然可以避免这种情况。在这种情况下,具有查找与覆盖索引的计划之间的执行时间差可能是不可估量的。即使需要物理I/O的地方,如果读取数量很少,您仍然可能不在乎。 (数据缓存中表格的数据页面的可能性取决于许多因素,并且特定于您的硬件和情况)。

如果需要一些物理I/O,则查询计划中存在的优化仍然可以减少查找的影响。如果SQL Server期望查找的数量很大,则可以选择明确地对嵌套循环的行进行分类,并按照非群集键的顺序加入驾驶查找。这种重新排序可促进对非集群索引的顺序读取,这可能比您的硬件上的随机I/O快得多。

有或没有明确的排序,嵌套环连接起来,查找可能具有 WithOrderedPrefetch 或者 WithUnorderedPrefetch 存在的属性。无论哪种情况,查询执行引擎都在索引键流中“向前看”,以驱动查找和问题 读书 阅读。这个想法是发行 异步 将请求读取到I/O系统的数据页面,以便很快需要,因此在查找需要数据页面时,它已经存在于内存中。

在理想的条件下(低碎片,良好的查询计划,高性能I/O系统),读取机制可能足够快,以防止甚至大型平行查询计划等待I/O才能完成。在企业版中尤其如此,它可以发出非常大的单个I/O请求(如果存储器使用,则每个请求最多2MB)。另一方面,在不理想的情况下(更正常!)条件下,您的查询可能会遭受可怕的等待,因为它等待了很长的I/O队列,或者无法足够努力地驱动I/O系统。关键查找的最坏情况确实可能很差。

概括

总而言之,您将 一般来说 想避免查找 这样做有意义的地方. 。对于小查询(将保持小),您可能会确定额外索引的开销(空间和维护)是没有道理的,因此,由于系统及其用户的更大需求,因此没有合理的态度。

最终,这是数据库开发和管理的艺术与科学的一部分。

许可以下: CC-BY-SA归因
不隶属于 dba.stackexchange
scroll top