给定日期范围的此查询的最快方式(最佳策略是什么)

8 t-sql sql-server sql-server-2005

我有一个表A,除了一些其他列之外,它还有一个startDate和一个结束dateDate作为2个datetime列.我有另一个表B,它有一个日期时间列调用它的日期列.这是在SQL Server 2005中.

这里的问题是:如何最好地设置索引等以获得以下内容:

select ....
 from A , B
where A.startDate >= B.dates
  and A.endDate < B.dates
Run Code Online (Sandbox Code Playgroud)

两个表都有几千条记录.

Qua*_*noi 7

更新:

在我的博客中查看此文章,了解使用计算列的查询的高效索引策略:

主要思想是我们只计算舍入lengthstartDate范围,然后使用相等条件(对B-Tree索引有用)搜索它们


MySQL和中SQL Server 2008你可以使用SPATIAL索引(R-Tree).

它们特别适合"选择记录范围内给定点的所有记录"这样的条件,这正是您的情况.

您存储start_dateend_date作为a的开头和结尾LineString(将它们转换UNIX为另一个数值的时间戳),使用索引对它们进行SPATIAL索引,并使用搜索LineString最小边界框(MBR)包含相关日期值的所有此类s MBRContains.

请参阅我的博客中有关如何执行此操作的条目MySQL:

以及简要的性能概述SQL Server:

可以应用相同的解决方案来IP针对存储在数据库中的网络范围搜索给定的.

此任务与您查询一起,是此类条件的另一个常用示例.

B-Tree如果范围可以重叠,则普通索引不好.

如果他们不能(而且你知道),你可以使用提出的精彩解决方案 @AlexKuznetsov

另请注意,此查询性能完全取决于您的数据分布.

如果你有大量的记录B和一些记录A,你可以只建立一个索引B.dates,让TS/CISA走.

这个查询将始终读取所有的行A并将使用Index SeekB.dates嵌套循环.

如果您的数据是以其他方式分布的,即您有很多行A但很少B,并且范围通常很短,那么您可以稍微重新设计一下表:

A

start_date interval_length
Run Code Online (Sandbox Code Playgroud)

,创建一个复合索引 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
Run Code Online (Sandbox Code Playgroud)


ba_*_*end -5

如果您需要优化,请尝试在查询分析器中运行此查询。