如何防止低效的 SQL 查询减慢数据库服务器的速度
Posted
技术标签:
【中文标题】如何防止低效的 SQL 查询减慢数据库服务器的速度【英文标题】:How can inefficient SQL queries be prevented from slowing a database server 【发布时间】:2013-10-17 22:10:45 【问题描述】:我有一个 ASP .NET 4.5 应用程序。维护页面上有一个文本框,允许管理用户编写直接针对 SQL Server 2008 数据库执行的 SQL。
有时,某个管理用户编写了一些低效的 SQL,SQL Server 进程开始耗尽服务器上的所有内存和 CPU 周期。然后我们必须启动和停止服务以使服务器再次响应。
有什么方法可以阻止这些查询消耗所有资源?这些查询返回的速度不足以让用户看到它们,因此可以取消查询。
编辑 我意识到阻止用户编写 SQL 查询会更好,但不幸的是我无法从应用程序中删除此功能。管理员用户不想接受教育。
【问题讨论】:
如果您将 max degree of parallelism 设置为无限制(或超过 1 个),您可以执行所有查询MAXDOP 1
以防止它们吃掉所有内核。
也就是说,我不知道有什么技术方法,除了限制连接上的CommandTimeout,或者监控和教育导致这些问题的人。
假设您有一个生产/登台设置,让管理员首先在登台上测试查询,这样重要的机器就不会被占用。即使在时间限制后终止查询,您也可能在此期间占用重要资源(在生产中不好)。
我们鼓励管理员在暂存系统上测试查询,但我们不能强迫他们这样做。
【参考方案1】:
您可以在服务器级别设置查询调控器,但不确定每个用户或每个连接/应用程序的限制。
http://technet.microsoft.com/en-us/magazine/dd421653.aspx
也就是说,允许用户直接输入 SQL 查询可能是一种糟糕/危险的做法。
【讨论】:
谢谢,在输入的任何 SQL 的开头添加“set query_governor_cost_limit 600”似乎已经阻止了任何过于疯狂的运行,而不会让用户感到不安。【参考方案2】:首先,我会确保这些查询没有锁定任何表(对每个运行的查询使用 NOLOCK 或 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED)。
就资源而言,我会考虑资源管理器之类的东西。我们将其用于生产 OLTP 系统上的任何临时报告。
Pinal Dave 有一篇很棒的博客文章。您还可以查看 Technet 或其他 MS 网站,了解它是什么以及如何设置它。
http://blog.sqlauthority.com/2012/06/04/sql-server-simple-example-to-configure-resource-governor-introduction-to-resource-governor/
【讨论】:
【参考方案3】:创建一个用户,该用户的权限不超过必要的权限。
为用户创建一些登录数据,您不会与编写查询的管理员共享这些数据。
创建一个面板/页面/应用程序,让他们在其中编写查询。您可以在此处添加在 RDBMS 系统级别不可用的其他约束。
您让您的用户访问此面板/页面/应用程序,他们将通过此运行查询。如果他们做了您不希望发现的任何事情,那么您只需发布您对权限和面板/页面/应用程序的修改。
【讨论】:
【参考方案4】:撇开允许用户构建和运行自己的查询的利弊不谈,一种解决方案可能是使用 SQL 2008/2012 附带的资源调控器。我认为它仅在企业版中可用,这可能意味着您无法使用它(您尚未在问题中指定版本)。
Technet 有一篇关于如何管理工作负载的文章,但基本上您可以将会话(基于登录详细信息或任何其他可识别信息)限制为仅使用一定百分比的 CPU 和/或内存。
【讨论】:
【参考方案5】:防止 SQL 使用内存/CPU 的最佳方法:不要让用户运行查询。
SQL Server 应该使用它可以使用的所有内存,因此内存使用(或 CPU 使用)不会成为重新启动 SQL 的理由。
默认情况下 .NET SqlCommand 超时为 30 秒。当它超时时,查询将被取消。查询可能需要一段时间才能取消,尤其是在您进行数据修改并且必须进行回滚时。查询正在运行/取消其他用户查询时可能会被阻止。这可能会使 SQL Server 看起来好像没有响应,但最终它会完成并且您的 CPU 使用率将恢复正常。但是内存将继续被 SQL Server 进程消耗。
【讨论】:
如果没有人可以访问,数据库的目的是什么?以上是关于如何防止低效的 SQL 查询减慢数据库服务器的速度的主要内容,如果未能解决你的问题,请参考以下文章
在某些情况下,为什么CTE(公用表表达式)与SQL Server中的临时表相比会减慢查询速度
当计划中未使用该索引时,为什么在SQL Server中添加索引会减慢查询速度?