【问题标题】:Speeding up a SQL view by pre-filtering results通过预过滤结果加速 SQL 视图
【发布时间】:2019-03-01 11:41:04
【问题描述】:

我有一个在一张非常大的桌子上运行的视图。

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 

【问题讨论】:

  • 请发布您的实际代码。视图不能包含临时表。第二 - 谓词下推应该工作
  • 嗯,好的,我目前正在使用 CTE 进行此操作 - 将转换
  • VeryLargeTable 上有哪些索引?当您有几分钟的空闲时间时,请阅读“XY 问题”:)
  • @Lukasz 可以是列的任意组合

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


【解决方案1】:

您可以将视图重写为内联 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 ...

【讨论】:

    猜你喜欢
    • 2013-06-29
    • 1970-01-01
    • 1970-01-01
    • 2012-07-05
    • 2018-08-18
    • 1970-01-01
    • 1970-01-01
    • 2015-02-02
    • 1970-01-01
    相关资源
    最近更新 更多