现在有一个大表,按照每日日期进行分区,分区函数指向的列为timestamp
列,然后这个大表还有一个非 unique 的device_id
列,并且以此列建立聚集索引。
当我需要查询某一天的某个device_id
的所有数据时, SQL 如下:
select * from table where device_id = 233 and datediff(day, timestamp, '2017-03-10') = 0
我发现查询的效率和分区之前比并没有较大的提升(耗时为原来的 50%),和预期有很大出入。
然后使用另一种日期限制条件:
select * from table where device_id = 233 and timestamp >= '2017-03-10' and timestamp < '2017-03-11'
查询的耗时为之前的 1/300~1/200 ,速度提升非常明显。
所以我想请教一下大家:当以日期为分区边界值时,使用日期函数并不能利用分区函数来限制查询的分区?换句话说,是不是日期函数对于表分区是无效的?有没有什么方法能在按日期分表的情况下同时利用日期函数?
感谢大家解答。
1
weizhiyao008 2017-03-10 10:07:17 +08:00 1
where 条件里面不要含有计算
|
2
medivh 2017-03-10 10:11:31 +08:00 1
|
3
Alias4ck 2017-05-04 17:37:51 +08:00
你都说大表了。。把 where 条件修改一下 啊。。对所有的 timestamp 进行 datediff 肯定会慢啊(全表查询了)。。换成 timestamp=datediff(day, 0, '2017-03-10') 就好了
|
5
Alias4ck 2017-05-05 13:51:13 +08:00
@zrp1994 那就把 timestamp 转换为日期格式啊。而且你上面给出的也只是日期比对啊 。。。我在怀疑 timestamp 和没有时间戳的日期比对怎么减的。。。是按照 00 时 00 分 00 秒为标准吗?(原谅我没怎么用过 sqlserver,不太明白其中的语法)。。
|
6
Alias4ck 2017-05-05 14:27:07 +08:00
测试了下 用 getdate()语法获取的是当前日期包含时分秒,也是可以用上述给的 datediff 的语法的 应该是默认打上了 00 时 00 分 00 秒。所以这个是可行的
|
7
Alias4ck 2017-05-05 14:47:26 +08:00 1
刚才上面那个是验证我自己的想法。。不好意思了 尴尬。。。的确你说的我写的 timestamp=datediff(day, 0, '2017-03-10')是不行的。。。可以改写成 convert(varchar(10),timestamp,120)='2017-03-10'...这种方式应该是可行的吧。。。
|