ric*_*ent 22 t-sql sql-server sql-server-2005 query-hints sql-execution-plan
我在SQL Server中运行一个相当复杂的查询,运行视图,格式如下:
SELECT *
FROM myview, foo, bar
WHERE shared=1 AND [joins and other stuff]
ORDER BY sortcode;
Run Code Online (Sandbox Code Playgroud)
如上所示的查询计划显示了Sort
在决赛之前的操作SELECT
,这正是我所期望的.只有35个匹配的记录,查询在2秒内完成.
但是,如果我添加TOP 30
,查询需要将近3分钟!使用SET ROWCOUNT
同样慢.
查看查询计划,它现在似乎在连接和过滤器myview
之前对所有200多万条记录进行排序.
这个"排序"在查询计划中显示为索引上的sortcode
索引扫描,主表上的聚簇索引查找以及它们之间的嵌套循环,所有这些都在连接和过滤器之前.
如何SORT
在之前 强制SQL Server TOP
,就像TOP
未指定时一样?
我不认为构造myview
是问题,但为了以防万一,它是这样的:
CREATE VIEW myview AS
SELECT columns..., sortcode, 0 as shared FROM mytable
UNION ALL
SELECT columns..., sortcode, 1 as shared FROM [anotherdb].dbo.mytable
Run Code Online (Sandbox Code Playgroud)
本地mytable
有几千条记录,而mytable
在同一MSSQL实例的另一个数据库中有几百条记录.两个表都在各自的sortcode
列上都有索引.
Dam*_*ver 10
所以开始了"试图超越优化器(因为它并不总是最了解)"的不幸游戏.
您可以尝试将过滤部分放入子查询或CTE中:
SELECT TOP 30 *
FROM
(SELECT *
FROM myview, foo, bar
WHERE shared=1 AND [joins and other stuff]) t
ORDER BY sortcode;
Run Code Online (Sandbox Code Playgroud)
这可能足以迫使它首先过滤(但优化器在每个版本中都变得"更聪明",并且有时可以看到这样的恶作剧).或者您可能必须将此代码放入UDF中.如果您将UDF编写为多语句表值函数,并在其中进行过滤,然后使用TOP x
/ 查询该UDF,则您ORDER BY
很好地强制执行查询顺序(因为SQL Server当前无法针对多语句UDF 进行优化).
当然,考虑到它,引入UDF只是隐藏我们真正做的事情的一种方式 - 创建一个临时表,使用一个查询来填充它(基于WHERE过滤器),然后另一个查询TOP x
从temp中查找表.
归档时间: |
|
查看次数: |
14144 次 |
最近记录: |