简体   繁体   English

Mysql时区并从一天中选择行

[英]Mysql timezone and selecting rows from one day

I use MySQL DATETIME column to store date & time.我使用 MySQL DATETIME 列来存储日期和时间。 Dates are in UTC.日期采用 UTC。 I want to select item from one day.我想从一天中选择项目。 What i'm doing now:我现在在做什么:

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

note that the timezone depends on user请注意,时区取决于用户

Problem is that it is quite slow with table growing.问题是表格增长速度很慢。 Is there any solution how to make it faster?有没有办法让它更快?

Currently your query has to compute the conversion for every row of the database. 目前,您的查询必须计算数据库的每一行的转换。 You probably could make things better by converting the other way round, so that the conversion only occurs once (or actually twice, as you'll have to form a range). 你可能可以通过转换相反的方式使事情变得更好,这样转换只发生一次(或实际上两次,因为你必须形成一个范围)。 Then a proper index on datetime should make things pretty fast. 那么适当的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')

Or if you worry about a 23:60:00 leap second not getting matched by any query, you can do 或者如果你担心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')

In the latter form, you wouldn't have to add the hours PHP-side but instead could simply pass the date as a string parameter. 在后一种形式中,您不必添加PHP端的小时数,而是可以简单地将日期作为字符串参数传递。

Depending on your real goal, using TIMESTAMP instead of DATETIME may be a good solution. 根据您的真实目标,使用TIMESTAMP而不是DATETIME可能是一个很好的解决方案。

TIMESTAMP stores the datetime as UTC, converting as it stores and as it is fetched, from/to the local timezone. TIMESTAMP将日期时间存储为UTC,在存储和提取时转换为/从本地时区转换。 This way, what I read from your table is automatically different than what you stored (assuming we are in different timezones). 这样,我从你的表中读取的内容会自动与你存储的内容不同(假设我们处于不同的时区)。

Yes, use @MvG's approach of flipping the query. 是的,使用@ MvG翻转查询的方法。 Yes, use his second form. 是的,使用他的第二个表格。

And index the column. 并索引列。 In composite indexes, put the timestamp last, even though it is more selective. 在复合索引中,将时间戳放在最后,即使它更具选择性。

  1. DO NOT do SELECT * 不要做SELECT *
  2. Indexing - make sure apropriate colunms/id fields are indexed. 索引 - 确保索引适当的colunms / id字段。
  3. Do time-conversion php-side. 做时间转换php端。
  4. OR make sure you do 1 & 2 and it may be wrapped into a Stored Proc, passing timezone as param. 或者确保你做1和2并且可以将它包装到存储过程中,将时区作为参数传递。

Currently MySQL query will be as below:目前 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')

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM