我有一个表A,它有一个startDate和一个结束dateDate作为2个日期时间列除了一些更多的其他列.我有另一个表B有一个日期时间列调用它日期列.这是在sql Server 2005中.
这里的问题是:如何最好地设置索引等以获得以下内容:
select .... from A,B where A.startDate >= B.dates and A.endDate < B.dates
两个表都有几千条记录.
解决方法
更新:
在我的博客中查看此文章,了解使用计算列的查询的高效索引策略:
> Efficient date range query: SQL Server
主要思想是我们只为你的范围计算舍入长度和startDate,然后使用相等条件搜索它们(这对B-Tree索引很有用)
在MysqL和sql Server 2008中,您可以使用SPATIAL索引(R-Tree).
它们特别适合“选择记录范围内给定点的所有记录”这样的条件,这正是您的情况.
将start_date和end_date存储为LineString的开头和结尾(将它们转换为另一个数值的UNIX时间戳),使用SPATIAL索引对它们进行索引,并搜索其最小边界框(MBR)包含日期值的所有此类LineStrings问题是,使用MBRContains.
> Overlapping ranges: SQL Server
可以应用相同的解决方案来针对存储在数据库中的网络范围搜索给定的IP.
此任务与您查询一起,是此类条件的另一个常用示例.
如果范围可以重叠,则普通B树索引不好.
如果他们不能(而且你知道),你可以使用@AlexKuznetsov提出的出色解决方案
如果你在B中有很多记录而在A中有很少的记录,你可以在B.dates上建立一个索引,然后在A上使用TS / CIS.
此查询将始终读取A中的所有行,并将在嵌套循环中使用B.dates上的Index Seek.
如果您的数据以其他方式分布,我.即A中有很多行但B中很少,而且范围通常很短,那么你可以稍微重新设计一下你的表:
A start_date interval_length
,在A上创建一个复合索引(interval_length,start_date)
并使用此查询:
SELECT * FROM ( SELECT DISTINCT interval_length FROM a ) ai CROSS JOIN b JOIN a ON a.interval_length = ai.interval_length AND a.start_date BETWEEN b.date - ai.interval_length AND b.date