我需要以最快的方式查询一个包含 1,852,789,683
行且大小为 179.3GB
的表。我的条件是需要一整天(24 小时)日本时间。
查询:
SELECT COUNT(*) CNT
FROM info_table
WHERE DATE(CONVERT_TZ(created_at, '+00:00', '+09:00')) = 20141216;
我已经让它运行了将近一个小时,但仍未完成。有什么建议吗?
描述:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE info_table ALL NULL NULL NULL NULL 1793315059 Using where
最佳答案
您的查询将在 created_at
上计算该函数表中每个翻转行的列;这是一个完整的扫描。
要使MySQL能够对索引进行高效的范围扫描操作,需要在谓词中引用裸列,并且需要一个前导列为created_at
的索引。 ,查询需要采用以下形式:
WHERE created_at >= val1
AND created_at < val2
诀窍是开发 val1 和 val2,它们是返回时间戳上限和下限的表达式。
如果我们知道:
DATE(CONVERT_TZ(created_at, '+00:00', '+09:00')) = 20141216
然后我们知道:
CONVERT_TZ(created_at, '+00:00', '+09:00')) >= '2014-12-16'
AND CONVERT_TZ(created_at, '+00:00', '+09:00')) < '2014-12-17'
和(也许?)...
created_at >= CONVERT_TZ('2014-12-16','+09:00','+00:00')
AND created_at < CONVERT_TZ('2014-12-17','+09:00','+00:00')
我不确定 CONVERT_TZ
的行为函数,反转是否对您的案例中的所有值都等效。同样,“技巧”将是获取返回时间戳上限和下限的表达式。
<罢工>罢工>
<罢工>在我们的环境中,我们对数据库中的所有日期、日期时间和时间戳使用 GMT;我们使用 GMT 进行数据库连接。应用层进行适当的时区转换。当我需要做你正在做的事情时,我倾向于写这样的东西:
created_at >= '2014-12-16' + INTERVAL -9 HOUR
AND created_at < '2014-12-16' + INTERVAL 24-9 HOUR
罢工><罢工>罢工>
关于mysql - 基于时区快速查询大表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27528923/