我有一个名为 DATETIME 字段的表date_created
,需要使用这种查询检查一些数据:
SELECT * FROM table WHERE UNIX_TIMESTAMP(date_created) + $number < UNIX_TIMESTAMP()
没有 UNIX_TIMESTAMP() 函数可以做到这一点吗?也许现在())?如果是,它会更快吗?
没有 UNIX_TIMESTAMP() 函数可以做到这一点吗?也许现在())?
不完全是。虽然您可以执行以下操作,但它不会获得完全相同的结果:
SELECT * FROM `table` WHERE date_created + INTERVAL $number SECOND < NOW()
原因是,与 不同TIMESTAMP
,DATETIME
它既不打算也不能够及时表示特定实例;相反,它有效地表示日历/时钟的显示(不是同一件事)。
当使用上述查询时,它不通过 UTC 时间戳,比较只是一个问题,即现在的时钟是否会显示比数据库中记录的日期/时间晚(加上$number
秒)的日期/时间。
但是,当转换为 UTC 时间戳时,各个时钟显示的时区变得相关,并且由于许多时区不是恒定的(例如,它们经常在夏令时移动),多个DATETIME
值可能会产生相同的 UTC 时间戳。
例如:
CREATE TABLE `table` (date_created DATETIME);
INSERT INTO `table` VALUES ('2012-10-28 01:00:00'), ('2012-10-28 02:00:00');
然后比较在2012-10-28 02:00:00
英国运行时两个查询的结果:
您的原始查询:
SET SESSION time_zone = 'Europe/London';
SELECT *
FROM `table`
WHERE UNIX_TIMESTAMP(date_created) + 100
< UNIX_TIMESTAMP('2012-10-28 02:00:00');
上面的替代查询:
SELECT *
FROM `table`
WHERE date_created + INTERVAL 100 SECOND
< '2012-10-28 02:00:00';
如果是,它会更快吗?
可能(比较的字典顺序就足够了,而不是DATETIME
根据会话时区的规则解析并将值转换为 UTC,然后进行减法和符号检查),但我建议您执行自己的基准测试。
如果可能,应避免在 WHERE 子句中使用 eval 表达式。它会阻止正确使用索引。如果可能,在代码中进行数学运算并将值作为查询参数发送。