通过预过滤结果来加快SQL视图的速度

时间:2018-09-25 19:00:25

标签: sql-server tsql query-optimization sql-server-2016 sql-view

我有一个在非常大的桌子上操作的视图。

CREATE VIEW [myView]
AS

-- first part
WITH A AS (
SELECT MAX(Id), ResultId, LocationId, TeamId
FROM VeryLargeTable
GROUP BY ResultId, LocationId, TeamId)    
--second part
SELECT A.Id, A.TeamId, ROW_NUMBER() OVER (PARTITION BY ResultId, LocationId) RN  
FROM A
WHERE RN = 1
GO

现在运行诸如

之类的操作
SELECT * from [MyView] 
WHERE TeamId = 5

这很慢,因为它实际上是在执行

WITH A AS (
SELECT MAX(Id), ResultId, LocationId, TeamId
FROM VeryLargeTable
GROUP BY ResultId, LocationId, TeamId)    
--second part
SELECT A.Id, A.TeamId, ROW_NUMBER() OVER (PARTITION BY ResultId, LocationId) RN  
FROM A
WHERE RN = 1 AND TeamId = 5

我想知道的是如何构造该视图,以便它知道在第一部分中过滤TeamId = 5以便执行以下快速的代码

WITH A AS (
SELECT MAX(Id), ResultId, LocationId, TeamId
FROM VeryLargeTable
GROUP BY ResultId, LocationId, TeamId
WHERE TeamId = 5)    
--second part
SELECT A.Id, A.TeamId, ROW_NUMBER() OVER (PARTITION BY ResultId, LocationId) RN  
FROM A
WHERE RN = 1 

1 个答案:

答案 0 :(得分:1)

您可以将视图重写为Inline TVF:

CREATE FUNCTION dbo.my_func(@TeamId INT)
RETURNS TABLE
AS
RETURN
(
WITH A AS (
  SELECT MAX(Id), ResultId, LocationId, TeamId
  FROM VeryLargeTable
  WHERE TeamId = @TeamId OR @TeamId IS NULL
  GROUP BY ResultId, LocationId, TeamId
)    
--second part
SELECT A.Id, A.TeamId, ROW_NUMBER() OVER (PARTITION BY ResultId, LocationId) RN  
FROM A
WHERE RN = 1 
);

并查询:

SELECT *
FROM dbo.my_fun(5)
WHERE ...