当前位置: 代码迷 >> Sql Server >> 有关索引的一些有关问题
  详细解决方案

有关索引的一些有关问题

热度:81   发布时间:2016-04-24 09:17:53.0
有关索引的一些问题
1.
 我在表中把时间作为索引,并且选择了递减排序,每次第一条记录就是离现在时间最近的记录。那么现在可以肯定的是,以后每次插入的新数据,时间都比表中现有时间数据大,插入数据到第一个位置是不是会导致现有的数据发生移动?
2.
 我设置的时间索引,是datetime类型,是否可以设置为具体到天的索引,比如“今天”10:21和21:09的两条记录都在一个索引记录“今天”的指向区域之内?或者,是否可以设置二级索引来增加搜索效率?

------解决思路----------------------
插入数据到第一个位置是不是会导致现有的数据发生移动?
--> 不会. 仅需更新索引树里的节点.

我设置的时间索引,是datetime类型,是否可以设置为具体到天的索引,比如“今天”10:21和21:09的两条记录都在一个索引记录“今天”的指向区域之内?或者,是否可以设置二级索引来增加搜索效率?
--> SQL2005及以上可以用条件索引,即创建索引时加where条件.
------解决思路----------------------
第一个问题:有聚集索引,插入数据会移动,以下可以简单测试:
--	drop table tab
create table tab(dtime datetime,name nchar(990))

-- drop index ix_tab on tab
create clustered index ix_tab on tab(dtime desc)
-- create clustered index ix_tab on tab(dtime asc)

insert into tab(dtime,name)
select '2015-03-01 00:00:00.000','kk'
union all
select '2015-03-02 00:00:00.000','kk'
union all
select '2015-03-03 00:00:00.000','kk'

dbcc traceon(3604,-1)
dbcc ind(databaseName,tab,-1)
dbcc page(databaseName,1,412,3)

--插入最新日期
insert into tab(dtime,name)
select '2015-03-04 00:00:00.000','kk'

--插入到中间的日期
insert into tab(dtime,name)
select '2015-03-02 12:00:00.000','kk'

dbcc ind(databaseName,tab,-1)
dbcc page(databaseName,1,412,3)



按降序建索引,表中插入一行数据后,数据页旧的数据会往后移动,最新的将在第一页的首行。
如果分页,则会有索引页,索引页记录分页中的首行键列。


第二个问题:最好不要按天了,转换很麻烦,其实一个索引在datetime上按年月日统计都可以用到索引。
如果你按天了,又想查按年的,按月的,按时间的,都建索引吗,不好吧。1个就行了
如:
select * from tab where dtime>='2015-03-02' and dtime <DATEADD(d,1,'2015-03-02')--使用索引

select * from tab where convert(varchar(10),dtime,120)='2015-03-02' --不走索引





------解决思路----------------------
第二个问题补充一下,其实你是想按照datetime字段的年月日部分来搜索,类似CONVERT(DATE, time_column) = '2015-03-22',但是SQL Server中是没有函数索引的。所以,得换一种思路,利用日期数据转换为datetime字段后,时间部分是00:00:00.000的特点。例如,time_column >= CONVERT(DATETIME, '2015-03-22') AND time_column < DATEADD(day, 1, CONVERT(DATETIME, '2015-03-22')),即从3月22日的00:00:00(含)到3月23日的00:00:00(不含),那么也就是3月22日这一天了。
------解决思路----------------------
插入数据到第一个位置是不是会导致现有的数据发生移动?
答:这个完全不会!如果你的表有自增ID,你可以看到最后插入的记录,ID永远是最大的。
创建索引,检索数据时,数据库查询优化引擎,会根据索引进行优化查询,和数据的物理存储顺序无关。
------解决思路----------------------
引用:
Quote: 引用:

第二个问题:最好不要按天了,转换很麻烦,其实一个索引在datetime上按年月日统计都可以用到索引。
如果你按天了,又想查按年的,按月的,按时间的,都建索引吗,不好吧。1个就行了
如:
select * from tab where dtime>='2015-03-02' and dtime <DATEADD(d,1,'2015-03-02')--使用索引

select * from tab where convert(varchar(10),dtime,120)='2015-03-02' --不走索引

我所担心的是,随着数据表越来越大,按照datetime建立索引会导致索引文件越来越大(扩大的速度比按天建立索引快很多),检索效率一样会越来越差。我设计的检索,最小粒度是天,按年月什么的检索不就是把符合条件区间的索引对应的数据都输出出来吗?


如果这样的话,建议设计表datetime 分成两个字段 date 和 time,在date建立索引就行了,不知道现在还能不能改。


------解决思路----------------------
1.  如果是聚集索引,肯定会有数据的移动,越向后,这个发越是明显

2.  datetime 类型,本身可以包含 date  + time ,所你不会去建立一个另一个索引 。
查询某一天时,只要 

where crdate between convert(datetime,'2015-01-01 00:00:00') 
             and convert(datetime,'2015-01-01 23:59:59')
  相关解决方案