日期:2013-04-25  浏览次数:20349 次

有些查询天生就耗费大量资源。这与基本的数据库和索引问题有关。这些查询的效率并不低,由于查询优化器会以最无效的可能方式实现这些查询。然而,它们确实耗费大量资源,而且 Transact-SQL 面向集合的性质使这些查询看起来效率很低。查询优化器的智能水平无法消弭这些结构的固有资源成本。与不复杂的查询相比,这些查询的固有成本十分昂贵。虽然 Microsoft(r) SQL Server? 2000 使用最佳的访问计划,但遭到基础结构可能性的限制。

例如,下列类型的查询可能占用大量资源:

前往大结果集的查询

高度不独一的 WHERE 子句
不过有一些针对优化查询和提高查询功用的建议,其中包括:

添加更多的内存(尤其是如果服务器运转许多复杂查询而且其中几个查询执行很慢)。

在有多个处理器的计算机上运转 SQL Server。多个处理器使 SQL Server 得以利用并行查询。有关更多信息,请参见并行查询处理。

考虑重新编写查询。
如果查询使用游标,则确定如果使用效率更高的游标类型(如快速只进游标)或单纯查询能否更无效地编写游标查询。单纯查询的功用普通优于游标操作。一组游标语句通常是一个外循环操作,在此操作中,一旦使用内部语句便开始处理外循环内的每行,因此可考虑使用 GROUP BY 或 CASE 语句或改为使用子查询。

如果使用程序使用循环,可考虑在查询内放入循环。使用程序常包含带参数化查询的循环,该循环执行许多次并要求运转使用程序的计算机与 SQL Server 之间有网络往返。可改为使用临时表创建一个更复杂的查询。只需提供一个网络往返,查询优化器即会更好地优化这个查询。

不要对同一查询内的单个表使用多一般名以模仿索引交叉。模仿索引交叉已没有必要,由于 SQL Server 会自动考虑索引交叉并且可以在同一查询内的相反表上使用多个索引。例如,给出下列示例查询:
SELECT * FROM lineitem
WHERE partkey BETWEEN 17000 AND 17100 AND
shipdate BETWEEN ’1/1/1994’ AND ’1/31/1994"

SQL Server 可以在 partkey 和 shipdate 列上都使用索引,然后在两个子集之间执行哈希婚配以获得索引交叉。

只在必要时才使用查询提示。若查询使用在 SQL Server 晚期版本上执行的提示,则应在不指定提示的情况下对该查询进行测试。提示会防碍查询优化器选择更好的执行计划。有关更多信息,请参见 SELECT。
利用 query governor 配置选项和设置。可以使用 query governor 配置选项阻止执行长时间运转的查询,从而防止耗费系统资源。默认情况下,query governor 配置选项允许执行所有查询,而不考虑查询所需的时间。然而,可以将查询调控器设置到最大秒数,以允许执行所有连接的所有查询或只允许执行特定连接的查询。查询调控器基于估量的查询成本而不是实际的已用时间,因此没有任何运转时开销。它还在长时间运转的查询开始前便将其停止,而不是先运转这些查询直到达到某些预定义的限制为止。有关更多信息,请参见 query governor cost limit 选项和 SET QUERY_GOVERNOR_COST_LIMIT。