【发布时间】:2011-06-18 03:23:56
【问题描述】:
请多多包涵——我知道这很复杂。
我有一张包含公寓的表格,还有一张包含这些公寓的租约的表格。我的任务是从列表中选择“最相关”的租约。一般来说,这意味着最近的租约,但有一些怪癖使它比仅按日期排序更复杂。
这导致我在 View 中创建了这个公共表表达式查询,然后我在存储过程中与其他一些人 JOIN 以获得我需要的结果:
WITH TempTable AS (
SELECT l.BuildingID, l.ApartmentID, l.LeaseID, l.ApplicantID,
ROW_NUMBER() OVER (PARTITION BY l.ApartmentID ORDER BY s.Importance DESC, MovedOut, MovedIN DESC, LLSigned DESC, Approved DESC, Applied DESC) AS 'RowNumber'
FROM dbo.NPleaseapplicant AS l INNER JOIN
dbo.NPappstatus AS s ON l.BuildingID = s.BuildingID AND l.AppStatus = s.Code
)
SELECT BuildingID, ApartmentID, LeaseID, ApplicantID
FROM TempTable
WHERE RowNumber = 1
这有效并返回正确的结果。我面临的挑战是性能非常缓慢。
作为测试,我在存储过程中创建了一个临时表,而不是使用 View,并获得了更好的性能:
CREATE TABLE #Relevant (
BuildingID int,
ApartmentID int,
LeaseID int,
ApplicantID int,
RowNumber int
)
INSERT INTO #Relevant (BuildingID, ApartmentID, LeaseID, ApplicantID, RowNumber)
SELECT l.BuildingID, l.ApartmentID, l.LeaseID, l.ApplicantID,
ROW_NUMBER() OVER (PARTITION BY l.ApartmentID ORDER BY s.Importance DESC, MovedOut, MovedIN DESC, LLSigned DESC, Approved DESC, Applied DESC) AS 'RowNumber'
FROM dbo.NPleaseapplicant AS l INNER JOIN
dbo.NPappstatus AS s ON l.BuildingID = s.BuildingID AND l.AppStatus = s.Code
WHERE (l.BuildingID = @BuildingID)
DROP TABLE #Relevant
乍一看,这对我来说并不重要。我听说临时表对性能非常不利。问题是我能够更好地限制临时表中的查询,其中包含我在视图中无法使用的 WHERE 子句。对于表中 16 座建筑物的超过 10,000 个租约,使用 WHERE 进行过滤的能力可能会删除 90% - 95% 受影响的行。
考虑到所有这些,我在这里有什么明显的遗漏吗?我是否对可能导致可怕性能的视图做错了什么,还是只是临时表中较小的结果集击败了 CTE 中的无限制结果集?
编辑:我应该补充一点,选择“最相关租约”的业务逻辑是系统中许多报告的关键。这就是为什么它一开始就放在 View 中的原因。视图为我们提供了“一次编写,多次使用”的能力,而存储过程中的临时表需要为系统中的每个其他存储过程重新创建。丑陋的。
编辑#2:我可以使用基于表格的函数而不是视图吗?这是否允许我限制预先受影响的行,并且仍然在与其他表的 JOIN 中使用结果数据集?如果它有效 - 并且具有良好的性能 - 这将允许我将业务逻辑保留在一个地方(函数),而不是在几十个存储过程中复制它。
【问题讨论】:
-
请问什么版本的 SQL Server? 2008 年以上的 ROW_NUMBER 更好
-
1.您如何从视图中选择数据(是否通过建筑物 ID 进行过滤)? 2.请发布表结构和索引 3.请发布两个查询(坏和好)的执行计划
-
不幸的是,它是 SQL Server 2005。由托管公司管理,因此我无法控制升级。
-
数据是从带有 BuildingID @oryol 过滤器的视图中选择的。执行计划的图形版本非常庞大。有没有更好的展示方式?
-
执行 set showplan_text on 和之后的查询。另请添加用于创建数据库结构(表和索引)的帖子脚本
标签: sql sql-server performance common-table-expression temp-tables