如何防止低效的 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 查询减慢数据库服务器的速度的主要内容,如果未能解决你的问题,请参考以下文章

单一条件大幅减慢 SQL 查询速度

在某些情况下,为什么CTE(公用表表达式)与SQL Server中的临时表相比会减慢查询速度

当计划中未使用该索引时,为什么在SQL Server中添加索引会减慢查询速度?

为啥没有聚合的结束 Group By 会减慢我的查询速度?

MongoDB,即使它们形成分区,查询字段也会减慢查询速度吗?

如何加快对 SQL 服务器的多行插入?