Sybase中高效过滤DateTime列当前日期记录的最优方法咨询
嘿,针对你这个千万级数据量的表,用datepart拆分年月日的写法确实踩了性能坑——因为函数直接作用在date_sent列上时,数据库没法利用这列上的索引,只能被迫全表扫描,这对1100-1200万条记录来说,速度肯定慢得让人抓狂。下面给你几个高效的实现方案,都是能完美利用索引的:
方法一:范围查询(最通用、性能天花板)
直接构造当天的时间范围,用大于等于当天零点、小于第二天零点的条件过滤,这是所有数据库都支持的最优写法,能直接触发date_sent上的索引:SELECT * FROM TABLE_NAME WHERE date_sent >= '2018-04-16' AND date_sent < '2018-04-17';解释下:
'2018-04-16'默认对应当天的00:00:00,'2018-04-17'则是第二天的零点,这样就精准覆盖了当天所有时间点的记录,数据库可以快速通过索引定位到目标数据,不会做无用的全表扫描。方法二:日期类型转换(SQL Server专属简化写法)
如果你用的是SQL Server 2012及以后版本,还可以用CAST把date_sent转成DATE类型来匹配,这个写法更直观,而且同样是可利用索引的(属于sargable查询):SELECT * FROM TABLE_NAME WHERE CAST(date_sent AS DATE) = '2018-04-16';不过要注意,SQL Server 2008及更早版本中这个写法可能无法触发索引,所以如果是老版本,还是优先用方法一的范围查询。
方法三:动态获取当天日期(无需硬编码)
如果你的需求是每次查询都过滤当前系统日期的记录,不用硬写死2018-04-16,可以用数据库函数动态生成时间范围,同样高效:-- SQL Server 写法 SELECT * FROM TABLE_NAME WHERE date_sent >= CAST(GETDATE() AS DATE) AND date_sent < DATEADD(DAY, 1, CAST(GETDATE() AS DATE));这样不管哪天执行,都会自动匹配当天的所有记录,而且全程利用索引,性能拉满。
最后再敲个重点:查询要尽量写成「可搜索参数(sargable)」形式,简单说就是别在要过滤的列上套函数(除非是数据库明确支持的sargable函数),这样数据库才能用索引快速定位数据。千万级数据量下,索引的利用与否,直接决定了你的查询是秒出结果还是卡到崩溃。
内容的提问来源于stack exchange,提问作者LPP

