当我在CTE中使用视图时,引用CTE的每个子查询似乎都会重新查询视图。每个子查询都会重复执行计划的大块。从表中选择时不是这种情况。这是预期的吗?有没有办法解决它?
WITH cte AS (
SELECT v.id
FROM test_view AS v
)
SELECT TOP 25 *,
(SELECT COUNT(*) FROM cte) AS subquery
FROM cte
我正在使用SQL Server 2005
编辑:
我正在尝试从包含以下查询的页面中的视图中获取数据。我需要视图中的总行数,与搜索匹配的行数以及匹配行的子集。从表中选择时这很有效,但使用视图会导致重复执行CTE。我试图从马丁的答案中以各种不同的方式强制实现中间物化,但没有任何运气。
WITH tableRecords AS (
SELECT *
FROM example_view
),
filteredTableRecords AS (
SELECT *, ROW_NUMBER() OVER (ORDER BY id ASC) AS tableRecordNumber
FROM tableRecords
WHERE 1 = 1
)
SELECT *,
(SELECT COUNT(*) FROM tableRecords) AS totalRecords,
(SELECT COUNT(*) FROM filteredTableRecords) AS totalDisplayRecords
FROM filteredTableRecords
WHERE tableRecordNumber BETWEEN 1 AND 25
ORDER BY tableRecordNumber ASC
答案 0 :(得分:2)
是的,这在很大程度上是预期的。
请参阅Provide a hint to force intermediate materialization of CTEs or derived tables
对于您问题中的查询,您可以执行此操作
WITH CTE AS
(
SELECT v.id,
count(*) OVER () AS Cnt
FROM test_view AS v
)
SELECT TOP 25 *
FROM CTE
ORDER BY v.id
答案 1 :(得分:0)
我建议你重新编写你的查询,如下所示
我对您的查询做了一些改进
每次执行sql脚本时都会调用select子句中的子查询,因此实际上可以使用交叉应用来提高性能。
;WITH tableRecords AS(
SELECT *
FROM example_view
),
filteredTableRecords AS (
SELECT *, ROW_NUMBER() OVER (ORDER BY id ASC) AS tableRecordNumber
FROM tableRecords
),TotalNumber
(
SELECT (SELECT COUNT(1) FROM tableRecords) AS totalRecords,
(SELECT COUNT(1) FROM filteredTableRecords) AS totalDisplayRecords
)
SELECT *
FROM filteredTableRecords F
CROSS APPLY TotalNumber AS T
WHERE tableRecordNumber BETWEEN 1 AND 25
ORDER BY tableRecordNumber ASC