带日期部分的索引视图,日期部分上的查询未使用索引
Indexed view with datepart, query on datepart is not using the index
我需要在 datepart(day, BornDate)
and/or 个月之前在一个有几百万行的 table 上进行查询,这非常 CPU 密集。
我尝试将索引视图与日期部分列一起使用,甚至在索引视图本身的 datepart(day, BornDate)
列上创建非聚集索引。但是执行计划仍然告诉我查询是在基础 table.
上使用 datepart
计算的
我 运行 的查询如下:
set statistics time on
SELECT count(1) FROM [dbo].[DemandsBornDateParts] where borndateday = 5 OPTION (RECOMPILE)
set statistics time off
我总是将它与针对基础 table:
的相同查询进行比较
set statistics time on
select count(1) from dbo.Demands where DAY(borndate) = 5
set statistics time off
它们都显示几乎相同的查询计划,具有几乎相同的子树成本、CPU 和运行时间,都使用谓词 datepart(day,[dbo].[Demands].[BornDate])=(5)
进行聚簇索引扫描
视图定义如下:
GO
--Set the options to support indexed views.
SET NUMERIC_ROUNDABORT OFF;
SET ANSI_PADDING, ANSI_WARNINGS, CONCAT_NULL_YIELDS_NULL, ARITHABORT,
QUOTED_IDENTIFIER, ANSI_NULLS ON;
GO
--Create view with schemabinding.
IF OBJECT_ID ('dbo.DemandsBornDateParts', 'view') IS NOT NULL
DROP VIEW dbo.DemandsBornDateParts ;
GO
CREATE VIEW dbo.DemandsBornDateParts
WITH SCHEMABINDING
AS
SELECT id,
Datepart(DAY, borndate) AS BornDateDay,
Datepart(MONTH, borndate) AS BornDateMonth,
Datepart(YEAR, borndate) AS BornDateYear
FROM DBO.demands
GO
--Create an index on the view.
CREATE UNIQUE CLUSTERED INDEX [PK_dbo.DemandsBornDateParts]
ON dbo.DemandsBornDateParts (Id);
GO
CREATE NONCLUSTERED INDEX [IX_BornDateDay] ON [dbo].[DemandsBornDateParts]
(
[BornDateDay] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
如何才能使用 persisted/indexed 列,而无需一遍又一遍地重新计算 datepart
?我不能使用持久化列,我需要使用视图。
在查询中的视图名称后添加 WITH(NOEXPAND)
。来自 Table Hints 的文档:
NOEXPAND
Specifies that any indexed views are not expanded to access underlying tables when the query optimizer processes the query. The query optimizer treats the view like a table with clustered index. NOEXPAND applies only to indexed views.
来自同一页上的Remarks on Using NOEXPAND:
To force the optimizer to use an index for an indexed view, specify the NOEXPAND option.
我需要在 datepart(day, BornDate)
and/or 个月之前在一个有几百万行的 table 上进行查询,这非常 CPU 密集。
我尝试将索引视图与日期部分列一起使用,甚至在索引视图本身的 datepart(day, BornDate)
列上创建非聚集索引。但是执行计划仍然告诉我查询是在基础 table.
datepart
计算的
我 运行 的查询如下:
set statistics time on
SELECT count(1) FROM [dbo].[DemandsBornDateParts] where borndateday = 5 OPTION (RECOMPILE)
set statistics time off
我总是将它与针对基础 table:
的相同查询进行比较set statistics time on
select count(1) from dbo.Demands where DAY(borndate) = 5
set statistics time off
它们都显示几乎相同的查询计划,具有几乎相同的子树成本、CPU 和运行时间,都使用谓词 datepart(day,[dbo].[Demands].[BornDate])=(5)
视图定义如下:
GO
--Set the options to support indexed views.
SET NUMERIC_ROUNDABORT OFF;
SET ANSI_PADDING, ANSI_WARNINGS, CONCAT_NULL_YIELDS_NULL, ARITHABORT,
QUOTED_IDENTIFIER, ANSI_NULLS ON;
GO
--Create view with schemabinding.
IF OBJECT_ID ('dbo.DemandsBornDateParts', 'view') IS NOT NULL
DROP VIEW dbo.DemandsBornDateParts ;
GO
CREATE VIEW dbo.DemandsBornDateParts
WITH SCHEMABINDING
AS
SELECT id,
Datepart(DAY, borndate) AS BornDateDay,
Datepart(MONTH, borndate) AS BornDateMonth,
Datepart(YEAR, borndate) AS BornDateYear
FROM DBO.demands
GO
--Create an index on the view.
CREATE UNIQUE CLUSTERED INDEX [PK_dbo.DemandsBornDateParts]
ON dbo.DemandsBornDateParts (Id);
GO
CREATE NONCLUSTERED INDEX [IX_BornDateDay] ON [dbo].[DemandsBornDateParts]
(
[BornDateDay] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
如何才能使用 persisted/indexed 列,而无需一遍又一遍地重新计算 datepart
?我不能使用持久化列,我需要使用视图。
在查询中的视图名称后添加 WITH(NOEXPAND)
。来自 Table Hints 的文档:
NOEXPAND
Specifies that any indexed views are not expanded to access underlying tables when the query optimizer processes the query. The query optimizer treats the view like a table with clustered index. NOEXPAND applies only to indexed views.
来自同一页上的Remarks on Using NOEXPAND:
To force the optimizer to use an index for an indexed view, specify the NOEXPAND option.