性能连接日期在开始日期和结束日期之间的行

时间:2015-01-15 16:18:39

标签: mysql join inner-join outer-join

根据2个日期时间之间的日期时间,我有2个表,每个表需要加入几千行。

select SQL_NO_CACHE * from A 
left outer join R on R.ActivityDate > A.StartDate and R.ActivityDate < A.EndDate;

目前查询速度很慢。我已经尝试添加索引但是根据explain的输出没有使用它们。这种查询的适当索引策略是什么?使用between并不代替&lt; &GT;似乎没有什么区别。

如果执行直接连接,则查询速度提高13倍(返回的行数减少7%)但逻辑上我需要返回不匹配的行。当额外行数太少时,我不希望2种连接类型之间的区别如此之大。为什么外连接这么慢?

感谢任何帮助或想法。

mysql> describe A;
+-----------+--------------+------+-----+---------+-------+
| Field     | Type         | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+-------+
| StartDate | datetime     | NO   |     | NULL    |       |
| EndDate   | datetime     | NO   |     | NULL    |       |
| Data      | varchar(100) | NO   |     | NULL    |       |
+-----------+--------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

mysql> describe R;
+--------------+----------+------+-----+---------+-------+
| Field        | Type     | Null | Key | Default | Extra |
+--------------+----------+------+-----+---------+-------+
| ActivityDate | datetime | NO   |     | NULL    |       |
| Leads        | int(11)  | NO   |     | NULL    |       |
+--------------+----------+------+-----+---------+-------+
2 rows in set (0.00 sec)

2 个答案:

答案 0 :(得分:1)

执行LEFT JOIN将强制显示A中的所有行,而不管匹配

STRAIGHT JOIN或INNER JOIN只会产生与ON子句相匹配的行

答案 1 :(得分:1)

请尝试以下方法:

select SQL_NO_CACHE 
   * 
from A 
left outer join R 
  on ((R.ActivityDate - A.StartDate) * (R.ActivityDate - A.EndDate)) / 
      (CASE WHEN ABS((R.ActivityDate - A.StartDate) * (R.ActivityDate - A.EndDate)) = 0 
            THEN 1 
            ELSE ABS((R.ActivityDate - A.StartDate) * (R.ActivityDate - A.EndDate)) 
       END) = -1

上面的on子句在逻辑上等于你问题中提到的那个。

只有满足(R.ActivityDate - A.StartDate) * (R.ActivityDate - A.EndDate)条件时,产品(R.ActivityDate > A.StartDate) and (R.ActivityDate < A.EndDate)才为负数的原因。

这是因为上述条件(R.ActivityDate - A.StartDate) > 0 and (R.ActivityDate - A.EndDate) < 0的小变换。

请检查执行时间是否会有所改善,因为您的查询中没有> <比较。

我希望它有所帮助。