我使用 MySQL DATETIME 列来存储日期和时间。日期采用 UTC。我想从一天中选择项目。我现在在做什么:
SELECT * FROM data WHERE DATE(CONVERT_TZ(datetime, 'UTC', 'Australia/Sydney')) = '2012-06-01'
请注意,时区取决于用户
问题是表格增长速度很慢。有什么解决方案可以让它更快吗?
我使用 MySQL DATETIME 列来存储日期和时间。日期采用 UTC。我想从一天中选择项目。我现在在做什么:
SELECT * FROM data WHERE DATE(CONVERT_TZ(datetime, 'UTC', 'Australia/Sydney')) = '2012-06-01'
请注意,时区取决于用户
问题是表格增长速度很慢。有什么解决方案可以让它更快吗?
目前,您的查询必须计算数据库每一行的转换。您可能可以通过反过来转换来使事情变得更好,以便转换只发生一次(或实际上两次,因为您必须形成一个范围)。然后一个适当的索引datetime
应该会让事情变得非常快。
SELECT * FROM data
WHERE datetime BETWEEN CONVERT_TZ('2012-06-01 00:00:00', 'Australia/Sydney', 'UTC')
AND CONVERT_TZ('2012-06-01 23:59:59', 'Australia/Sydney', 'UTC')
或者,如果您担心23:60:00
任何查询都无法匹配闰秒,您可以这样做
SELECT * FROM data
WHERE datetime >= CONVERT_TZ('2012-06-01', 'Australia/Sydney', 'UTC')
AND datetime < CONVERT_TZ('2012-06-01' + INTERVAL 1 DAY, 'Australia/Sydney', 'UTC')
在后一种形式中,您不必在 PHP 端添加小时数,而是可以简单地将日期作为字符串参数传递。
根据您的实际目标,使用TIMESTAMP
代替DATETIME
可能是一个很好的解决方案。
TIMESTAMP
将日期时间存储为 UTC,在存储和获取时从/到本地时区进行转换。这样,我从您的表中读取的内容自动与您存储的内容不同(假设我们位于不同的时区)。
是的,使用@MvG 翻转查询的方法。是的,使用他的第二种形式。
并索引该列。在复合索引中,将时间戳放在最后,即使它更具选择性。
目前 MySQL 查询如下:
SELECT * FROM data
WHERE datetime >= CONVERT_TZ('2012-06-01', '+00:00', '+10:00')
AND datetime < CONVERT_TZ('2012-06-01' + INTERVAL 1 DAY, '+10:00', '+00:00')