数据库同步工具
sqlserver,Mysql数据同步软件

SQL提示代码分析-使用提示(PE004-7)

在线QQ客服:1922638

专业的SQL Server、MySQL数据库同步软件

“由于SQL Server查询优化器通常会选择最佳执行计划,因此我们建议仅由经验丰富的开发人员和数据库管理员作为最后的手段使用提示”。
Microsoft SQL Server文档

确实,不应对此进行任何讨论,因为文档中的上述警告对其进行了很好的总结。但是,我对数据库开发人员的沮丧感到同情,他们看到可用的提示范围不断扩大,或者看到提示在商业数据库应用程序中的广泛使用,其中有些听起来可以帮助解决他们的查询性能问题。需要说明提示的危险。

SQL提示具有一些与性能相关的代码分析规则,这些规则会警告您使用索引提示(PE004),连接提示(PE005),表提示(PE006)和查询提示(PE007)。

我曾经是开发团队的负责人,负责管理电信数据库系统的操作。当我在SQL代码中找到提示时,我严格禁止使用所有提示(除外)。这在小组中造成了一点不适感,因为他们可以看到在SQL Server的源中使用了提示,并且他们认为这是一种微调SQL的可接受方法。似乎曾经装饰过PC正面的”涡轮按钮”曾经使一切运行得更快。

我同意允许任何提示,只要开发人员能够解释他们为什么需要它,做什么,获得什么,可伸缩性的后果以及效果关于ACID合规性。我还要求他们准备一份维护计划,以识别和重新测试所有提示,以响应数据分布的变化,响应升级到新的SQL Server版本或应用新的Service Pack来验证提示仍然提供最佳性能。提示的使用很快消失了。

我讨厌暗示所有提示都是不好的,只是鲁only地使用它们。对查询提示的需求总是很少见的,尽管有可怕的警告,但微软仍会不断引入查询提示。最常见的情况是,如果查询优化器无法生成好的计划或提供稳定性能的计划,则通常使用提示,这通常是在对行数的估计非常错误时发生的。更复杂,或者它们变得太聪明。

面对无法获得最佳计划的查询时,一种更好的方法是退回并编写更简单的方法。运行缓慢的查询自然是告诉您的一种方法您正在以错误的方式进行操作。通常,您使用错误的方法来获取信息,或者数据库设计在某种程度上存在缺陷。这种缺陷通常是索引问题。我几乎从未成功过成功地”提示”了一个问题,即使微软称之为”最后的手段”。我意识到,在实用主义的现实世界中,有时不可能做得更多,而不是只用录音带做补救措施,但始终值得记住的是,当您升级SQL Server版本或升级SQL Server版本时,实用主义行为可能会变成定时炸弹。当数据库中的数据发生更改或索引被更改,并且优化器无法响应时,更改查询计划。

让我们以表提示作为经典示例。由于提示查询仍然在目标表上获得了(模式稳定性)锁定,并且如果与数据修改语句一起使用,也会被错误命名。实际上,它仅确保提示查询在该表上不获取共享锁,并且本质上是在事务期间允许进行脏读的指令,这意味着并发运行的任何数据修改事务都不会被阻止也可以将提示应用于数据修改事务时,另一个查询仍可以读取”运行中”数据,这意味着它可能读取从未提交的数据,可能是因为提示交易随后回滚。

如果您确实需要在事务处理期间允许对表进行脏读,那么最好使用等效且内容更多的提示。这就像您已设置在隔离级别工作的查询是一种过时的数据,已经处于维护模式以进行数据修改(和)

如果您确实使用它,那么,在工作正常的OLTP系统中,自然会出现各种错误,具体取决于时间安排,但是它们可能包含交易中的错误(例如错误601) ),总计,doppelganger数据(两次见过数据),时间旅行数据(同一行中来自不同” commits”的列数据)或幻像读取之类的不正确的汇总。如果您使用其他方法以外的方法,甚至可能导致索引损坏一个。

一个人可能认为带有表提示的查询能够不管表上现有的锁如何完成它的鲁ck工作,但是当另一个查询持有一个(模式修改)锁时,它会死于跟踪由DDL操作发出。另外,由于使用了提示,查询也阻止了DDL操作(例如索引维护),因为它已发出了锁定。

如果使用提示的原因是为了避免锁定和阻塞的开销,那么更好的方法是使用基于快照的隔离级别之一。一种选择是允许事务使用默认隔离级别,但数据库选项设置为””。这意味着查询将看到语句开头存在的数据的事务一致性快照。这样可以避免脏读,但不需要事务来获取共享的读锁。

为防止所有读取现象(脏读取,不可重复读取,幻像读取),可以将database选项设置为,然后在会话级别使用命令指定隔离级别。 。这样可以确保事务中的语句获取事务开始时存在的已提交数据的快照。

不能说使用总是错误的,特别是因为它们在SQL Server的元数据功能的来源中很明显。之所以使用它们是因为较高的隔离级别会带来风险。导致在非用户数据结构上引起不必要的争用。这是一个非常极端的情况。

很难说在查询必须读取大型只读表中大部分行的情况下使用它是错误的。但是,即使不是一个不错的选择,也最好改用隔离级别,例如或基于快照的版本。

另一个极端情况是必须在生产数据库中执行诊断查询。您要做的最后一件事是意外阻止其他用户。在这种情况下,即使您无法期望确切的值,也可以带来价值。

可能需要合理使用提示的另一个时间是临时的权宜之计,需要在开发中使用不同的查询计划来测试性能不佳的查询,以弄清为什么优化器未使用最佳的-执行策略。它可能会导致您获取过时的分布统计信息或覆盖索引中缺少列。

我听说它建议在其中只包含静态数据且不会更改的数据库上使用是可以的。但是,此类数据库有一种在您不期望的时候突然更改数据的习惯。另一方面,如果您将数据库设置为,则无论如何都不需要提示,因为共享锁不会被读取。仅限数据库。

如果您追加到查询,它将覆盖(禁用)该查询发出的任何其他表提示。您可以通过将其添加到计划指南中来对所有查询强制使用此”替代”提示。没有人会对珍贵的提示消失感到不安,开发人员可以继续相信他们的提示确实做得很好(请参阅《计划指南》中的”覆盖不良表提示”)。

通常情况下,对于SQL Server,这些功能按所宣传的那样工作。提示是一个例外。它们根本不是提示,而只是指令。它们通常按照它们所说的去做,但是并不总是存在很大的弊端:必须随着数据大小或分布的变化而不断对其进行检查和评估。 ,或者随着索引策略的变化而变化。每当升级SQL Server时,都必须重新检查提示。

他们移开了查询优化器的控制权,并通常谴责数据库执行策略存在时间扭曲。当查询优化器做出错误选择时,并不是因为它愚蠢,而是因为它愚蠢。不是。这是因为您的查询过于晦涩难懂,它所依据的查询信息不正确,或者您提供的索引不符合您所查询的要求。要进行不典型的圣经引用,使用提示就像巴兰使用鞭子在驴上,因为它不肯移动,事实证明,驴比他更具感知力。

使用提示就像Balaam在驴上使用鞭子,因为它不肯移动。 title =

未经允许不得转载:数据库同步软件|Mysql数据同步软件|sqlserver数据库同步工具|异构同步 » SQL提示代码分析-使用提示(PE004-7)

分享到:更多 ()

syncnavigator 8.6.2 企业版

联系我们联系我们