很久没写blog,不是懒,实在是最近我这的访问速度不好,用firefox经常上传不了图片 .......

今天无意发现了SQL Server 2008 Datetime Cast 成 Date 类型可以使用索引,分享一下:

测试环境:

USE TEMPDB
GO

CREATE TABLE TB
(
ID INT IDENTITY(1,1) PRIMARY KEY,
NAME VARCHAR(200),
OPTIME DATETIME DEFAULT GETDATE()
)
GO
DECLARE @I INT = 1
WHILE @I<10001
BEGIN
    INSERT INTO TB(NAME) SELECT 'A'+LTRIM(@I)
    SET @I=@I+1
END
GO
INSERT INTO TB(NAME,OPTIME) SELECT 'A10001','2010-05-27 16:25:20.117'
GO
CREATE INDEX IX_OPTIME ON TB(OPTIME)
GO

由上面的T-sql可以看出,如果我们查 2010年5月27的数据,应该只有一条。
为了更明显说明以下四种写法的区别,打开IO/执行计划开关,并且选中执行结果包含实际执行计划

SET STATISTICS IO ON
SET STATISTICS PROFILE ON 


以下是四种写法:

第一种写法:

SELECT * FROM TB WHERE CONVERT(VARCHAR(10),OPTIME,120)='2010-05-27'

消息结果:

  (1 row(s) affected)
  表 'TB'。扫描计数 1,逻辑读取 40 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

执行计划:

    
通过上面的执行计划,可以看到是聚集索引扫描,会扫描所有的索引叶,这不是我们希望的,它无法有效利用索引.

第二种写法:

SELECT * FROM TB WHERE LTRIM(YEAR(OPTIME))+'-'+LTRIM(MONTH(OPTIME))+'-'+LTRIM(DAY(OPTIME))='2010-5-27'

消息结果:

  (1 row(s) affected)
  表 'TB'。扫描计数 1,逻辑读取 40 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

执行计划:

    

同样,第二种方法和第一种一样,同样低效.

第三种写法:

SELECT * FROM TB WHERE OPTIME BETWEEN '2010-05-27 00:00:00.000' AND '2010-05-27 23:59:59.999' 

消息结果:
  (1 row(s) affected)
  表 'TB'。扫描计数 1,逻辑读取 4 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
执行计划:

    
由上面的结果和执行计划可以看出,这个写法是有效的利用了非聚集索引,效率很高.但需要自己补充好这一天的范围.即'00:00:00.000' AND '23:59:59.999' .

第四种写法:

SELECT * FROM TB WHERE CAST(OPTIME AS DATE)='2010-05-27'

消息结果:
  (1 row(s) affected)
  表 'TB'。扫描计数 1,逻辑读取 4 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

执行计划:
     
从上面的结果我们可以看到,这种写法虽然用了cast转变了数据类型,但依然可以有效使用索引,读取的page数是4,与第三种写法相同,同样高效.  

通过查看执行计划StmtText字段发现:
SELECT * FROM [TB] WHERE CONVERT([date],[OPTIME],0)=@1
  |--Nested Loops(Inner Join, OUTER REFERENCES:([tempdb].[dbo].[TB].[ID]))
       |--Nested Loops(Inner Join, OUTER REFERENCES:([Expr1006], [Expr1007], [Expr1005]))
       |    |--Compute Scalar(DEFINE:(([Expr1006],[Expr1007],[Expr1005])=GetRangeThroughConvert('2010-05-27','2010-05-27',(62))))
       |    |    |--Constant Scan
       |    |--Index Seek(OBJECT:([tempdb].[dbo].[TB].[IX_OPTIME]), SEEK:([tempdb].[dbo].[TB].[OPTIME] > [Expr1006] AND [tempdb].[dbo].[TB].[OPTIME] < [Expr1007]),  WHERE:(CONVERT(date,[tempdb].[dbo].[TB].[OPTIME],0)='2010-05-27') ORDERED FORWARD)
       |--Clustered Index Seek(OBJECT:([tempdb].[dbo].[TB].[PK__TB__3214EC27753864A1]), SEEK:([tempdb].[dbo].[TB].[ID]=[tempdb].[dbo].[TB].[ID]) LOOKUP ORDERED FORWARD)

执行计划将'2010-05-27'得到了Expr1006和Expr1007,然后再走索引查找:OPTIME>Expr1006 and OPTIME<Expr1007.

那么Expr1006和Expr1007是否就是'2010-05-26 23:59:59.998' 和'2010-05-28 00:00:00.000' 呢? 我不知道,但是我看像.. 你觉得呢?

    

如有错误,请指正,谢谢.

SQL Server 2008 Datetime Cast 成 Date 类型可以使用索引(转载)相关推荐

  1. oracle date 转换 timestamp,Oracle timestamp类型转换成date类型

    今天需要根据时间判断,统一修改某一个字段的数据.然后打开数据库发现,时间类型为timestamp类型.如下: 然后呢,这对我不是喝口水就可以解决的问题吗? 解决方案如下:我需要改这张表某个字段的内容, ...

  2. SQL Server 2008 各种DateTime的取值范围

    在SQL SERVER中DATETIME表示的时间为00:00:00到23:59:59.997,它的时间精度为1/300秒,在使用时会舍入到舍入到 .000..003 或 .007 秒三个增量.如下表 ...

  3. [转帖]真TM长的:SQL Server 2008存储结构——GAM和SGAM、PFS结构、IAM结构、DCMBCM

    谈到GAM和SGAM,我们不得不从数据库的页和区说起. https://blog.csdn.net/snowfoxmonitor/article/details/49991015 一个数据库由用户定义 ...

  4. SQL Server 2008存储结构——GAM和SGAM、PFS结构、IAM结构、DCMBCM

    谈到GAM和SGAM,我们不得不从数据库的页和区说起. 一个数据库由用户定义的空间构成,这些空间用来永久存储用户对象,例如数据库管理信息.表和索引.这些空间被分配在一个或多个操作系统文件中. 当我们创 ...

  5. SQL Server 2008 R2如何开启数据库的远程连接

    SQL Server 2008 R2如何开启数据库的远程连接 转载于:https://www.cnblogs.com/macT/p/10213025.html

  6. 在win server 2003上安装SQL Server 2008的步骤

    1.安装Microsoft .NET Framework 3.5 Service Pack 1,下载地址:http://www.microsoft.com/zh-cn/download/confirm ...

  7. SQL Server 2008 序列号

    SQL Server 2008 序列号: Developer: PTTFM-X467G-P7RH2-3Q6CG-4DMYB Enterprise:   JD8Y6-HQG69-P9H84-XDTPG- ...

  8. sqlserver200864位下载_sqlserver2008 64位|sql server 2008 R2 64位企业版下载 - 121下载站

    sql server 2008 R2 64位企业版是微软官方发布的64位版本,支持win7.win8等操作系统.sql server 2008 R2是最新版本的数据库软件,可以有效地提升企业内部数据库 ...

  9. sql server 中将datetime类型转换为date,或者time

    sql server 中将datetime类型转换为date,或者time 2008年01月14日 星期一 14:46 这个转换总是记不住,用到的时候就找,现贴上来,以备查用. datetime类型转 ...

最新文章

  1. TCP和UDP传输特点
  2. 简单的python抢红包脚本-这个Python脚本牛逼了,秒抢红包就算了,还能无视撤回消息...
  3. css样式继承规则详解
  4. boost::gil::static_transform用法的测试程序
  5. CNN 神经网络tricks 学习总结
  6. 内存问题提醒!结构体+protobuf做协议体发送!序列化
  7. get mysql options_mysql命令的选项options
  8. Spring MVC-学习笔记(5)spring MVC的文件上传、下载、拦截器
  9. Django - 模型层 - 关系类型字段
  10. 自学c语言需要什么要求,学习c语言需要什么基础
  11. java长连接转短连接_HTTP的长连接和短连接转换接口(API)
  12. epson机器人编程 范例_Epson机械手简单实例编程
  13. ~蓝杰那些事儿~2014.06.21.~胡先生和魏小姐的故事
  14. 那些年 用过的经典App
  15. 软件工程阶段性总结(四)——测试和维护
  16. robot framework 实例:126邮箱登录
  17. LIKE视频网站无法登录服务器,解析视频地址失败,更换服务器也不行
  18. 计算机中存储器的最小单位是什么意思,计算机内存储器的最小存储单位是什么...
  19. 头条搜索官网认证说明
  20. 奋斗与首付,谁更能承载生命之重?

热门文章

  1. vplex实施手册_VPLEX 运维及异构存储双活使用实例技术 | 在线答疑
  2. android select下拉列表_Python+selenium自动化之下拉列表操作(一)
  3. 乔治亚理工学院计算机专业,乔治亚理工学院
  4. java歌词添加,分享 :java实现 歌词文件的智能命名解决方法
  5. Ubuntu MySQL 重新安装
  6. java 反射api_个人编程学习网 - Java-操作反射其他的API
  7. java 改变文件路径_在C#中改变文件路径
  8. 基金指数温度怎么算_壁挂炉采暖费怎么算?从两千到八百,内行人教你别再花冤枉钱...
  9. 化工计算机软件基础考试题,化工原理模拟试题(一)及答案.doc
  10. 【转载】2008年世界最大50家石油公司综合排名(按六项指标综合测算)