更新:
请参阅我的博客中的这篇文章,了解使用计算列的查询的高效索引策略:
主要思想是我们只为您的范围计算四舍五入的length 和startDate,然后使用相等条件搜索它们(这对B-Tree 索引很有用)
在 MySQL 和 SQL Server 2008 中,您可以使用 SPATIAL 索引 (R-Tree)。
它们特别适用于“选择记录范围内给定点的所有记录”这样的条件,这正是您的情况。
您将start_date 和end_date 存储为LineString 的开头和结尾(将它们转换为另一个数值的UNIX 时间戳),使用SPATIAL 索引对它们进行索引并搜索所有例如LineStrings,其最小边界框(MBR)包含有问题的日期值,使用MBRContains。
在我的博客中查看此条目,了解如何在MySQL 中执行此操作:
以及SQL Server 的简要性能概述:
可以应用相同的解决方案来针对存储在数据库中的网络范围搜索给定的IP。
此任务以及您的查询是此类条件的另一个常用示例。
如果范围可以重叠,普通的B-Tree 索引就不好。
如果他们不能(你知道的),你可以使用@AlexKuznetsov提出的绝妙解决方案
另请注意,此查询性能完全取决于您的数据分布。
如果您在B 中有很多记录,而在A 中有少量记录,您可以在B.dates 上建立一个索引,然后让A 上的TS/CIS 去。
此查询将始终从A 读取所有行,并将在嵌套循环中使用B.dates 上的Index Seek。
如果您的数据以其他方式分布,i。 e. 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