在datetime范围内加速连接表的最佳实践

时间:2014-06-03 16:45:15

标签: sql sql-server datetime

我有两个具有日期时间范围的表(date_fromdate_to)。加入表格的最佳方法是,检查第一个表格上的date_fromdate_to范围是否与第二个表格上的日期时间范围重叠?

我已将datetime列转换为毫秒并在其上创建索引。我有如下查询,但工作不是那么快(两个表中大约100 000行)。有什么建议可以加速这种查询吗?

SELECT t1.*, t2.*
FROM t1
INNER JOIN t2 
ON t2.id = (
   /* TOP 1: need to get only first matched row */
   SELECT TOP 1 id FROM t2 WHERE t2.date_from >= t1.date_from 
                             AND t2.date_from <= t1.date_to
)

2 个答案:

答案 0 :(得分:1)

请考虑以下事项:

          start               end
            |                  |
A  <----->  |                  |
B      <----|----->            |
C    <------|------------------|---->
D           |   <----------->  |
E           |          <-------|-->
F           |                  |   <----->
            |                  |

与我们的开始和结束日期重叠的方案是B,C,D和E.相反,A和F不重叠。

注意两组之间一致吗?

所有重叠end 之前开始,start 之后完成

因此,为了获得重叠,伪SQL将如下所示:

SELECT *
FROM   your_table
 INNER
  JOIN other_table
    ON other_table.start_date <= your_table.end_date
   AND other_table.end_date   >= your_table.start_date

答案 1 :(得分:0)

如果你只想要t2的前1行,我建议使用CROSS APPLY

SELECT  *
FROM    t1
        CROSS APPLY
        (   SELECT  TOP 1 *
            FROM    t2
            WHERE   t2.date_from >= t1.date_from 
            AND     t2.date_from <= t1.date_to
            ORDER BY t2.date_from -- GET FIRST RECORD
        ) t2;

它实质上意味着您可以将连接和子查询合并为一个操作。我认为您使用SELECT *这一事实也可能代价高昂,这意味着即使您的日期列已编入索引,如果您需要所有数据,也必须执行查找以从t2检索所有数据从这两个表中,这是一个必要的恶,但如果你不这样做,那么你可以简化执行计划。