4

我使用 MySQL DATETIME 列来存储日期和时间。日期采用 UTC。我想从一天中选择项目。我现在在做什么:

SELECT * FROM data WHERE DATE(CONVERT_TZ(datetime, 'UTC', 'Australia/Sydney')) = '2012-06-01'

请注意,时区取决于用户

问题是表格增长速度很慢。有什么解决方案可以让它更快吗?

4

4 回答 4

10

目前,您的查询必须计算数据库每一行的转换。您可能可以通过反过来转换来使事情变得更好,以便转换只发生一次(或实际上两次,因为您必须形成一个范围)。然后一个适当的索引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 端添加小时数,而是可以简单地将日期作为字符串参数传递。

于 2012-08-01T08:22:30.530 回答
5

根据您的实际目标,使用TIMESTAMP代替DATETIME可能是一个很好的解决方案。

TIMESTAMP将日期时间存储为 UTC,在存储和获取时从/到本地时区进行转换。这样,我从您的表中读取的内容自动与您存储的内容不同(假设我们位于不同的时区)。

是的,使用@MvG 翻转查询的方法。是的,使用他的第二种形式。

并索引该列。在复合索引中,将时间戳放在最后,即使它更具选择性。

于 2018-06-23T15:27:15.233 回答
1
  1. 不要做选择 *
  2. 索引 - 确保索引适当的列/id 字段。
  3. 做时间转换php端。
  4. 或者确保您执行 1 和 2 并且它可能被包装到存储过程中,将时区作为参数传递。
于 2012-08-01T08:16:26.210 回答
0

目前 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')
于 2021-10-24T20:48:34.957 回答