SQL CTE 与视图
Posted
技术标签:
【中文标题】SQL CTE 与视图【英文标题】:SQL CTE vs View 【发布时间】:2021-01-17 14:22:47 【问题描述】:我有一个包含 65,000,000 行的事务表。
它分为大约几百个公司,每个公司又分为几百或几千个独立用户。
例子:
CREATE TABLE [dbo].[TestTransaction]
(
[Id] [int] IDENTITY(1,1) NOT NULL,
[CompanyId] [int] NULL,
[UserId] [int] NULL,
[LogDateTime] [datetime] NULL,
[Key1] [nvarchar](20) NULL,
) ON [PRIMARY]
GO
对于特定公司,我需要在用户的最小值LogDateTime
和用户的最大值LogDateTime
处获取所有用户和键值。
我想这样做:
;with cteGetMin as
(
select
CompanyId
, UserId
, LogDateTime
, Key1
, Row_Number() over (partition by UserId order by LogDateTime) as rowNumMin
from [dbo].[TestTransaction]
where CompanyId = @companyId
)
,cteGetMax as
(
select
CompanyId
, UserId
, LogDateTime
, Key1
, Row_Number() over (partition by UserId order by LogDateTime desc) as rowNumMax
from [dbo].[TestTransaction]
where CompanyId = @companyId
)
select
ma.CompanyId
,ma.UserId
,ma.Key1 as MaxKey
,ma.LogDateTime as MaxLogDateTime
,mi.Key1 as MinKey
,mi.LogDateTime as MinLogDateTime
from cteGetMax ma
join cteGetMin mi
on mi.CompanyId = ma.CompanyId
and mi.userId = ma.userId
and mi.rowNumMin = 1
and ma.rowNumMax = 1
我可以将每个 CTE 分解为一个单独的视图(或索引视图?),但这些视图将在 65,000,000 行的整个表上运行。
我的第一个想法是在每个 CTE 中添加 WHERE
子句会限制子结果,从而提高性能。
有什么想法吗?我应该保留 CTE,还是使用单独的视图?
编辑:我试图说明的一点是,在子查询或 CTE 中使用限制性 WHERE 子句是否更有效,或者拥有对整个 65,000,000 行进行操作的视图是否更有效?
【问题讨论】:
您使用的是哪个 dbms? 使用:SQL 2019 【参考方案1】:您实际上并不需要两个子查询和一个联接。相反,您可以使用row_number()
以两种方式枚举行,然后过滤一次,然后进行条件聚合:
select CompanyId, UserId,
max(case when rowNumMax = 1 then Key1 end) as MaxKey,
max(LogDateTime) as MaxLogDateTime,
min(case when rowNumMin = 1 then Key1 end) as MinKey,
min(LogDateTime) as MinLogDateTime
from (
select t.*,
row_number() over (partition by UserId order by LogDateTime) as rowNumMin,
row_number() over (partition by UserId order by LogDateTime desc) as rowNumMax
from [dbo].[TestTransaction] t
where CompanyId = @companyId
) t
where 1 in (rowNumMin, rowNumMax)
group by CompanyId, UserId
【讨论】:
以上是关于SQL CTE 与视图的主要内容,如果未能解决你的问题,请参考以下文章