mysql - 基于时区快速查询大表

标签 mysql performance

我需要以最快的方式查询一个包含 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/

相关文章:

mysql - 如何分析 mysql 数据库?

php - 使用 Codeigniter 从 MySql 行中读取 PHP 字符串

php - 使用 Doctrine 插入时 mysql 上的重复条目

php - UTF-8贯穿始终

javascript - 是什么导致相同数量的循环具有不同的性能?

android - 改造是否对被破坏的 fragment 提出请求?

mysql - 返回新记录的id

php - 查明该列是否支持 mysqli 中的 "Null"值

java - 如何获得性能来解码hadoop java代码的符号

PostgreSQL 查询非常慢,限制为 1