我新建了一张表
CREATE TABLE [dbo].[Table1](
[ID] [uniqueidentifier] NOT NULL,
[ProductNum] [int] ,
[SupplyNum] [int],
[StatisticsDate] [smalldatetime]
)
表中的数据按照天来存储的
现在业务的逻辑主要是需要查询给定时间段内 即 StatisticsDate >=给定时开始时间 和 StatisticsDate <给定的结束时间 之间的 ProductNum 和SupplyNum,我决得应该在StatisticsDate字段上建立一个聚集索引.
因为按照聚集索引的定义,StatisticsDate字段建立聚集索引后,数据是按照StatisticsDate来排序,即我需要查询指定时间的数据,只需要找到要检索的所有数据中的开头时间和结尾时间即可.但是Leader说不行,让我自己想一想.我想不明白.请各位给小弟解释一下.
谢谢.
CREATE TABLE [dbo].[Table1](
[ID] [uniqueidentifier] NOT NULL,
[ProductNum] [int] ,
[SupplyNum] [int],
[StatisticsDate] [smalldatetime]
)
表中的数据按照天来存储的
现在业务的逻辑主要是需要查询给定时间段内 即 StatisticsDate >=给定时开始时间 和 StatisticsDate <给定的结束时间 之间的 ProductNum 和SupplyNum,我决得应该在StatisticsDate字段上建立一个聚集索引.
因为按照聚集索引的定义,StatisticsDate字段建立聚集索引后,数据是按照StatisticsDate来排序,即我需要查询指定时间的数据,只需要找到要检索的所有数据中的开头时间和结尾时间即可.但是Leader说不行,让我自己想一想.我想不明白.请各位给小弟解释一下.
谢谢.
因为聚集索引要改变表数据存储的物理顺序 一般聚集索引在表里都为主键
看你的表 ID 应设置为主键 所以你这张表在 StatisticsDate建聚集索引就不太合适在StatisticsDate上建飞聚集索引吧
--===================================================
我在查询的时候 几乎不会用到 ID 来做查询判断的条件
而且数据是每天统计一次 然后插入表中 所以会存在重复的ID
非聚集索引 组合索引 本人觉得还可以
但是和Leader意见相反
比如部队人员编号表有100w的记录,每100个为一个连,
表的字段有id,连号,性别,
对于这种情况,id因为每条记录都不重复,所以其实不适合建立聚集索引
性别这种的除了男就是女,最多加个保密,所以也不适合做聚集索引
连号是最适合的聚集索引在查询数据的时候搜索到数据的最前面一条,然后再搜索到最后一条
然后把中间的记录返回,所以很快楼主你的表,不知道StatisticsDate列是不是取得getdate()之类的值,就是说每条记录可能都不一样
如果是这样的话,其实严格意义上并不适合作聚集索引但是如果你的表做其他的查询很少很少,那在这个字段上建立聚集索引也不错啊
反正也没有别的查询了,呵呵
因为我的SQL脚本每天跑一次 所以每一天生成的数据的StatisticsDate字段值都是一样的比如我今天跑SQL脚本 那么今天添加到表中的数据的StatisticsDate字段都是'20070114'按照书本的理论 应该是适合在StatisticsDate上建立聚集索引的阿
这种情况不是刚好可以用聚集索引吗?
是否有什么特别的业务需求?例如分布式数据库,或者要使用合并复制等....
如果没有的话,最好避免用uniqueidentifier做主键,主要原因是太相当耗费空间(16字节),
任何引用这个字段的索引都体积大增,性能减低,今后做查询时更耗费内存(都要装到内存里面)。
用自增列,int 类型(甚至bigint)就可以满足大多数需求的。比较一下:
uniqueidentifier 16字节
bigint 8字节 -2^63 (-9,223,372,036,854,775,808) to 2^63-1 (9,223,372,036,854,775,807)
int 4字节 -2^31 (-2,147,483,648) to 2^31-1 (2,147,483,647)
smallint 2字节 -2^15 (-32,768) to 2^15-1 (32,767)最好是避免在unqiueidentifier的列上建聚合索引。
MSSQL性能调试方面的专家Brad McGehee,专门提到过这个:
“If possible, avoid adding a clustered index to a GUID column (uniqueidentifier data type). GUIDs take up 16-bytes of storage, more than an Identify column, which makes the index larger, which increases I/O reads, which can hurt performance. While the performance hit will be minimal if you do decide to add a clustered index to a GUID column, every little bit ads up. [7.0, 2000, 2005] Updated 10-15-2004”比较适合见聚合索引的字段类型有:smallint, int, bigint, datetime。
并且如果是datetime用于聚合索引,这里面的值应该是不断增加的(随着时间的推移),并且很少修改。
比较适合按时间范围查询的,使between, <, > 更为有效。这些都比较比较符合LZ的情况。建议:
1) ID字段使用int类型的自增列
2) 在StatisticsDate建聚合索引
注:在datetime上建聚合索引是少有的能优化使用between, <, > 进行时间范围查询的手段,虽然有些限制,但LZ这里的情况是没有问题的。
LZ的leader肯定是个垃圾,别听他的,按照自己想的做
--------------------------------------
呵呵,请leader给解释一下,看什么说的。也许另有高见呢。
不过这种事也没有必要较真,你可以照他说的去做,
等今后性能上出问题了,你可以再改索引,一比较就知道谁的方法好了。
如果速度也还可以的话(也许你的数据量根本也不大),那就无所谓的。
但要考虑:1磁盘(数据库)上有足够的空闲空间2 这表有经常被更新,插入等操作如果这样的话,看具体情况来定。听听leader的声音,然后告诉大家结果
可以在StatisticsDate列建聚集索引
这个字段有非常多互不相同的值,(因为是精确到分钟的)建议使用非聚集索引。
如果查询返回结果基本固定而且字段不多的话,可考虑索引覆盖。
1011 0x784F002
1011 0x784F003
1011 0x784F004
1011 0x784F005
1011 0x784F006
1011 0x784F007还是类似
1011 0x784F001
1011 0x784F007
----------------------------
建聚焦索引不限定一定要是唯一值(即主键或有唯一索引),
如果同一个值出现多次,SQL会在内部自动附加一个4字节的序列号,以保证每个值都是唯一的。
这会增加一点内部开销。所以,最好就是在有唯一值的字段上建聚集索引。
1.如果仅仅就我对表的操作,即按照 ID 和 StatisticsDate 组合查询的话,那么适合在这张表建立聚集索引;
2.但是每张表只能建一个聚集索引,所以聚集索引资源是宝贵的,建聚集索引就值得考虑;
3.考虑今后可能会增加表的字段,或者对表进行其他的业务操作,所以就全局来说,不适合在StatisticsDate 字段上建立聚集索引。谢谢大家,马上结帖。hoho