【发布时间】:2010-01-25 23:08:45
【问题描述】:
在包含 1500000 行的 MySql 表上运行以下选择大约需要 5 分 30 秒。
SELECT * FROM my_table WHERE timestamp BETWEEN UNIX_TIMESTAMP('2008-04-23 01:37:02') AND UNIX_TIMESTAMP('2008-04-23 01:37:03')
[Executed: 25/01/10 5:32:47 EST PM ] [Execution: 231094/ms]
在上述查询中转换和替换 UNIX_TIMESTAMP 函数返回的值将大大减少持续时间:
SELECT UNIX_TIMESTAMP('2008-04-23 01:37:02'), UNIX_TIMESTAMP('2008-04-23 01:37:03')
UNIX_TIMESTAMP('2008-04-23 01:37:02') UNIX_TIMESTAMP('2008-04-23 01:37:03')
---------------------------------------- ----------------------------------------
1208911022 1208911023
SELECT * FROM my_table WHERE timestamp BETWEEN 1208911022 AND 1208911023
[Executed: 25/01/10 5:58:27 EST PM ] [Execution: 11875/ms]
时间戳列的类型是INT(11)。
我们不是在这里讨论索引 - 我不是数据库的所有者,但我会要求在该列上建立索引。
我想问你为什么两个查询之间存在巨大的持续时间差异?
似乎 timestamp 列中的每个 INT(11) 值都转换为 UNIX_TIMESTAMP 返回的值的类型! p>
更新 1
MySql 版本:
SELECT VERSION()
5.1.23-rc-log
解释结果:
EXPLAIN SELECT * FROM my_table WHERE timestamp BETWEEN UNIX_TIMESTAMP('2008-04-23 01:37:02') AND UNIX_TIMESTAMP('2008-04-23 01:37:03')
id select_type table type possible_keys key key_len ref rows Extra
----- -------------- ------------- ------- ---------------- ------ ---------- ------ -------- -----------
1 SIMPLE my_table ALL (null) (null) (null) (null) 15046061 Using where
EXPLAIN SELECT * FROM my_table WHERE timestamp BETWEEN 1208911022 AND 1208911023
id select_type table type possible_keys key key_len ref rows Extra
----- -------------- ------------- ------- ---------------- ------ ---------- ------ -------- -----------
1 SIMPLE my_table ALL (null) (null) (null) (null) 15046061 Using where
更新 2
SELECT * FROM my_table WHERE timestamp >= UNIX_TIMESTAMP('2008-04-23 01:37:02') AND timestamp <= UNIX_TIMESTAMP('2008-04-23 01:37:03')
[Executed: 26/01/10 10:29:52 EST AM ] [Execution: 264172/ms]
EXPLAIN SELECT * FROM my_table WHERE timestamp >= UNIX_TIMESTAMP('2008-04-23 01:37:02') AND timestamp <= UNIX_TIMESTAMP('2008-04-23 01:37:03')
id select_type table type possible_keys key key_len ref rows Extra
----- -------------- ------------- ------- ---------------- ------ ---------- ------ -------- -----------
1 SIMPLE my_table ALL (null) (null) (null) (null) 15046061 Using where
似乎 >= 和
【问题讨论】:
-
请发布
EXPLAIN SELECT * FROM my_table WHERE timestamp BETWEEN UNIX_TIMESTAMP('2008-04-23 01:37:02') AND UNIX_TIMESTAMP('2008-04-23 01:37:03')和EXPLAIN SELECT * FROM my_table WHERE timestamp BETWEEN 1208911022 AND 1208911023的结果。这将告诉您正在使用哪些索引。 MySQL is not 在第一个查询中使用索引而 is 在第二个查询中使用索引很可能。 -
添加了 EXPLAIN 计划和 MySQL 版本。
-
感谢您发布
EXPLAIN声明的结果。我现在可以看到没有使用任何索引。能否请您发布SHOW CREATE TABLE my_table;的结果,以便我们查看表上有哪些索引?