优化在DATE(datetime)= date时加入的SQL查询?

时间:2010-06-24 10:15:40

标签: sql mysql optimization query-optimization

我有两个表:一个有一个日期时间列,另一个有一个日期列。

我想加入这两个表:

SELECT
  t1.dt,
  t2.d
FROM
  table1 t1,
JOIN
  table2 t2
ON
  DATE(t1.dt) = t2.date

但显然,这会导致t1.dt上的索引被杀死。

解决这个问题的最佳策略是什么?最简单的方法是向t1添加一个新列(并将其设置为date(t1.dt)),但我不喜欢复制数据的想法。

有没有一种巧妙的解决方法?

3 个答案:

答案 0 :(得分:1)

您的日期时间列包含日期和时间部分。由于您希望单独索引日期部分,因此将datetime列拆分为两个单独的列是有意义的,一列用于时间部分,另一列用于日期部分。然后可以对日期列建立索引,并在索引中使用索引。使用这种方法,您根本不会复制任何数据。

答案 1 :(得分:0)

我不太确定,但这可能会迫使MySQL在从日期时间中减去日期时迭代所有行。您应该使用EXPLAIN来确定。你可以通过这样做来解决这个问题:

(t1.dt >= "2010-06-24 00:00:00"
  AND t1.dt < ("2010-06-24 00:00:00" + INTERVAL 1 DAY) )

编辑:刚尝试使用Date(),似乎MySQL仍然使用索引:

CREATE TEMPORARY TABLE t1 (
    dt DATETIME,
    INDEX iDt (dt)
);

INSERT INTO t1 VALUES
    (NOW()),
    (NOW() - INTERVAL 1 DAY),
    (NOW() - INTERVAL 1 DAY),
    (NOW() - INTERVAL 2 DAY);

CREATE TEMPORARY TABLE t2 (
    dt DATETIME,
    INDEX iDt (dt)
);

INSERT INTO t2 VALUES
    (NOW()),
    (NOW() - INTERVAL 1 DAY),
    (NOW() - INTERVAL 1 DAY),
    (NOW() - INTERVAL 2 DAY);

# t1: Using index. t2: Using where+index
EXPLAIN EXTENDED
SELECT
    *
FROM t1
    JOIN t2 ON DATE(t1.dt) = DATE(t2.dt)

答案 2 :(得分:0)

试试这个。这将使用索引

SELECT 
  t1.dt, 
  t2.d 
FROM 
  table1 t1, 
JOIN 
  table2 t2 
ON 
  t1.dt>=t2.date  and
  t1.dt <(t2.date + INTERVAL 1 DAY)