Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
CTE内部的SQL Server视图导致性能不佳_Sql_Sql Server_Sql Server 2005_View_Common Table Expression - Fatal编程技术网

CTE内部的SQL Server视图导致性能不佳

CTE内部的SQL Server视图导致性能不佳,sql,sql-server,sql-server-2005,view,common-table-expression,Sql,Sql Server,Sql Server 2005,View,Common Table Expression,当我在CTE内部使用视图时,引用CTE的每个子查询似乎都会重新查询该视图。对于每个子查询,都有大量重复的执行计划。从表中选择时,情况并非如此。这是预期的吗?有什么办法绕过它吗 WITH cte AS ( SELECT v.id FROM test_view AS v ) SELECT TOP 25 *, (SELECT COUNT(*) FROM cte) AS subquery FROM cte 我正在使用SQLServer2005 编辑: 我正在尝试使用下面的查询从

当我在CTE内部使用视图时,引用CTE的每个子查询似乎都会重新查询该视图。对于每个子查询,都有大量重复的执行计划。从表中选择时,情况并非如此。这是预期的吗?有什么办法绕过它吗

WITH cte AS (
    SELECT v.id
    FROM test_view AS v
)
SELECT TOP 25 *,
    (SELECT COUNT(*) FROM cte) AS subquery
FROM cte
我正在使用SQLServer2005

编辑:

我正在尝试使用下面的查询从页面中的视图获取数据。我需要视图中的总行数、匹配搜索的行数以及匹配行的子集。这在从表中选择时效果很好,但使用视图会导致重复执行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

是的,这在很大程度上是意料之中的

对于问题中的查询,您可以这样做

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=1,则不需要删除,因为它总是正确的
  • 每次执行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
    

  • 谢谢你的链接和答案。不幸的是,我无法使用任何链接的方法强制实现CTE。如果有机会,请查看我上面的编辑。@davishmcclurg-最佳的优化方法将取决于视图的定义、涉及的表的大小、筛选器表达式的性质和可用的索引。没有一种方法永远是最好的。