Ускорение представления SQL путем предварительной фильтрации результатов - PullRequest
0 голосов
/ 25 сентября 2018

У меня есть представление, работающее с очень большой таблицей.

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 голосов
/ 25 сентября 2018

Вы можете переписать свой вид как 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 ...
...