我有一个大型数据库,有许多表,每个表有几百万条记录,性能很重要。出于这个问题的目的,让我们使用一个更简单的例子。
我在DST小时的时间戳上对两个表执行JOIN时遇到问题。 DST发生在今年11月5日凌晨2点,时区美国/纽约。基本上,凌晨2点,时钟设置回到凌晨1点,所以2017-11-05 1:00:00"发生了两次"。
现在,我的服务器是UTC,我有以下表格:
表1:
2017-11-05 04:00:00 1.00
2017-11-05 05:00:00 2.00
2017-11-05 06:00:00 3.00
表2:
2017-11-05 04:00:00 4.00
2017-11-05 05:00:00 5.00
2017-11-05 06:00:00 6.00
在这些表中,时间戳采用UTC和TIMESTAMP类型。
我想创建一个视图:
SELECT t1.time, t1.value, t2.value FROM test1 t1 LEFT JOIN test2 t2 ON t1.time = t2.time
产生以下输出:
2017-11-05 04:00:00 1.00 4.00
2017-11-05 05:00:00 2.00 5.00
2017-11-05 06:00:00 3.00 6.00
当我的服务器设置为时区UTC时,这是正确的。但是,我的用户位于加拿大东部,时区和#34; America / New_York"因为我不希望他们每次需要访问数据时都设置用户连接时区,所以我将服务器时间设置为" America / New_York"。当我执行相同的SELECT语句并且服务器设置为EST时区时,我得到以下结果:
2017-11-05 00:00:00 1.00 4.00
2017-11-05 01:00:00 2.00 5.00
2017-11-05 01:00:00 3.00 5.00
2017-11-05 01:00:00 2.00 6.00
2017-11-05 01:00:00 3.00 6.00
为什么JOIN在结果(时区独立)上执行而不是在时区的实际时间戳上执行?
我应该看到:
2017-11-05 00:00:00 1.00 4.00
2017-11-05 01:00:00 2.00 5.00
2017-11-05 01:00:00 3.00 6.00
分别在EDT,EST和EST中有3行,即使我不需要查看该信息。
我不想使用:
SELECT t1.time, t1.value, t2.value FROM test1 t1 LEFT JOIN test2 t2 ON unix_TIMESTAMP(t1.time) = unix_timestamp(t2.time)
这是出于性能原因,因为在JOIN非常昂贵和缓慢之前将数百万条记录转换为UNIX_TIMESTAMP。
正如我所说,我宁愿不将服务器时间设置为UTC,因为我不想让我的用户每次想要访问本地时区的数据时都将时区设置为America / New_York。