Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 日期时间部分(如年、月)的SQL Server索引_Sql Server_Sql Server 2008_Tsql_Indexing - Fatal编程技术网

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日)中,这会变得很棘手。