mysql - 为什么SQL查询要访问所有行而且很慢

标签 mysql performance indexing

“阅读”表包含今天每 40 秒获取的读数。查询返回 180 秒期间的平均值。 'time_stamp' 已编入索引。下面的查询返回合理数量的行(几百)但访问所有行并且表越大变得越慢。 WHERE 子句似乎并没有将其仅限于今天的行。

EXPLAIN SELECT DATE_FORMAT(time_stamp, '%Y-%m-%dT%T+00:00') , AVG(temp_c) FROM reading WHERE DATE(time_stamp) = CURDATE() GROUP BY round(UNIX_TIMESTAMP(time_stamp) / 180)

表架构: CREATE TABLE <code>reading</code> ( <code>id</code> bigint(20) NOT NULL AUTO_INCREMENT, <code>time_stamp</code> timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, <code>temp_c</code> float NOT NULL, <code>pressure_hpa</code> float NOT NULL, <code>wind_speed_kt</code> int(11) NOT NULL, <code>wind_dir_degree</code> int(11) NOT NULL, <code>rain_mm</code> float NOT NULL, <code>rain_day_mm</code> float NOT NULL, <code>wind_gust_kt</code> int(11) NOT NULL, <code>humidity</code> float DEFAULT NULL, PRIMARY KEY (<code>id</code>), KEY <code>time_stamp</code> (<code>time_stamp</code>), KEY <code>time_stamp_idx</code> (<code>time_stamp</code>) ) ENGINE=InnoDB AUTO_INCREMENT=1747097 DEFAULT CHARSET=latin1;

Sample data

最佳答案

EXPLAIN SELECT 
    DATE_FORMAT(time_stamp, '%Y-%m-%dT%T+00:00') ,
    AVG(temp_c) 
FROM reading
WHERE DATE(time_stamp) = CURDATE() 
GROUP BY round(UNIX_TIMESTAMP(time_stamp) / 180) 

执行上述查询时,MySQL 优化器对索引扫描不感兴趣(可能是因为成本因素),而是启动全表扫描,问题似乎是因为 WHERE DATE(time_stamp) = CURDATE().

将您的 where 子句更改为 time_stamp >= CURDATE() 后,我发现使用了索引并且在避免完全扫描时获取的行数较少。

因此,您的最终查询将是:

EXPLAIN SELECT 
    DATE_FORMAT(time_stamp, '%Y-%m-%dT%T+00:00') ,
    AVG(temp_c) 
FROM reading
WHERE time_stamp >= CURDATE() 
GROUP BY round(UNIX_TIMESTAMP(time_stamp) / 180);

我怀疑 date(time_stamp) 使用索引时效率不高。讨论了类似的话题here (参见 ypercube 的回答)。

可以通过选择 round(UNIX_TIMESTAMP(time_stamp)/180) 来进一步改进上述查询,因为 UNIX_TIMESTAMP(timestamp) 不使用索引。但是,我不会再尝试了。

希望这对您有所帮助!

关于mysql - 为什么SQL查询要访问所有行而且很慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44367108/

相关文章:

mysql - 是否有任何信息表/矩阵显示 char、varchar、text、real、double、float、binary、set、int、integer、longtext 的属性?

Eclipse PyDev 完成挂起(再次)

c++ - 在 mex 函数中索引和访问元胞数组和矩阵的元素

sql - 改进此 SQL 查询的方法

C++ Trie 搜索性能

python - 根据值选择 pandas 数据框的列

php - 我如何在 Agiletookit 中调试与数据库相关的错误?攻击力4

php - 如何在创建主 ID 之前或同时获取它?

Android 每 2 小时以编程方式将 GPS 发送到 MySql 数据库

mysql - phpmyadmin 中的 sql 查询非常慢