Sql server 日期时间部分(如年、月)的SQL Server索引
是否可以在Sql server 日期时间部分(如年、月)的SQL Server索引,sql-server,sql-server-2008,tsql,indexing,Sql Server,Sql Server 2008,Tsql,Indexing,是否可以在DateTime部分建立索引,例如DATEPART(年,bp.[CreatedOn])和DATEPART(月,bp.[CreatedOn])?例如,我有以下T-SQL查询: DECLARE @year AS INT = 2012; DECLARE @month AS INT = 8; SELECT bp.Title, bp.CreatedOn FROM BlogPosts bp WHERE (DATEPART(YEAR, bp.[CreatedOn]) = @year) AND (D
DateTime
部分建立索引,例如DATEPART(年,bp.[CreatedOn])
和DATEPART(月,bp.[CreatedOn])
?例如,我有以下T-SQL查询:
DECLARE @year AS INT = 2012;
DECLARE @month AS INT = 8;
SELECT bp.Title, bp.CreatedOn FROM BlogPosts bp
WHERE (DATEPART(YEAR, bp.[CreatedOn]) = @year) AND (DATEPART(MONTH, bp.[CreatedOn]) = @month)
ORDER BY bp.CreatedOn;
这是我的执行计划:
目前,记录不多,因此性能方面不是一个大问题,但记录会随着时间的推移而增长。您最好使用datetime字段构造条件:
declare @startMonth datetime = '20120801'
SELECT bp.Title, bp.CreatedOn
FROM BlogPosts bp
WHERE bp.[CreatedOn] >= @startMonth
AND bp.[CreatedOn] < dateadd (month, 1, @startMonth)
ORDER BY bp.CreatedOn;
declare@startMonth datetime='20120801'
选择bp.Title,bp.CreatedOn
来自英国石油公司的博客帖子
其中bp.[CreatedOn]>=@startMonth
和bp。[CreatedOn]
这样,查询执行器将能够在CreatedOn上使用索引 是的,是否可以将指数放在年份和月份上。以下是一个例子:
create table testt(d datetime)
alter table testt add year as year(d) PERSISTED -- after marc_s advise. Thx
alter table testt add month as month(d) PERSISTED --
create index idx_year on testt(year)
create index idx_month on testt(month)
然而,我总是使用尼古拉解的一个变体,所以+1是尼古拉解
以下是如何将月份和年份重写为日期:
DECLARE @year AS INT = 2012;
DECLARE @month AS INT = 8;
DECLARE @from DATE = dateadd(month, (@year-1900)*12 + @month - 1, 0)
我建议您将日期部分存储在不同的字段中。显然,这是一个存在于您的领域中的需求,因此需要成为您的模型的一部分
您所失去的是,您必须为加载的每个模型构造日期时间或设置值,但这将是几个CPU周期。hmm,好主意!谢谢。所以,不可能在DateTime部分上创建索引?@tugberk可能,如果您使用持久计算列并对其进行索引。-1。这必须在所有记录上运行
dateadd
,因此必须加载所有记录(全表扫描)-性能非常差。我打赌您会在执行计划中看到。@Aliostad如果createdOn上有索引,这不会导致完整表扫描。即使没有,它的性能也会比(DATEPART(YEAR,bp.[CreatedOn])=@YEAR)…+1好得多。这只是一个简单的索引范围搜索。不知道添加单独的年和月列会如何帮助性能。如果有什么会影响性能的话,那就是每页的行数减少。更好的是,让这些计算列保持不变:ALTER TABLE dbo.TestT ADD MyMonth as MONTH(d)persistend
——这样,它们的值就不会在每次被访问时重新计算……这只是一个简单的查询,可以返回在给定月份创建的所有项目。不需要为此存储分解的日期。@MartinSmith这一个是的。但是正如我所说的,将会有(我假设)更多与日期相关的东西,所以我建议这样做。好吧,这是可能的,但是(我猜)你需要创建一个触发器来保持年和月列的同步,以防CreatedOn
被更改(尽管它不太可能被更改)。触发器??真正地不接触魔鬼的工具。将DateTime分解为单独的存储组件的一个缺点是,您必须重新设计一些使用DateTime免费获得的验证。例如,如果分别存储月、日和年,则可以插入无效日期,如2012年1月32日。当然,您可以添加范围检查约束,但在闰年(例如,2011年2月29日)中,这会变得很棘手。