mysql - 缓慢的 MySQL SELECT 性能

标签 mysql database

我有以下数据库架构: https://dl.dropbox.com/u/37915176/schema.PNG

我在 meter_relevation 中有超过 200 万条记录。数据来自多个电表,这些电表与具有 meter_history 表的电器(设备)相关联。

我尝试获取特定日期范围内的设备数据:

SELECT MR.* 
FROM device AS D, meter_history AS MH, meter AS M, meter_relevation AS MR
WHERE D.Id=MH.Id_Device 
   AND MH.Id_Meter=M.Id 
   AND M.Id=MR.Id_Meter 
   AND D.Id="8" 
   AND MR.Date>="2012-10-04" 
   AND MR.Date<="2012-10-04"

但是性能很慢,即使在指定的日期范围内没有记录,我也可以获得 10 秒。

我尝试了 EXPLAIN,我清楚地看到我的查询不是最优的,在 meter_relevation 表上列出了总行数,超过 200 万:https://dl.dropbox.com/u/37915176/explain.png

有什么建议吗?有一个更好的方法?当然我可以在客户端做一些工作并分成几个查询。但我想知道对于单个 SELECT 查询是否有更好的方法。

最佳答案

如果那是您正在运行的查询,它看起来不是最优的。你真的不需要 D 表,对吗?查看如何通过 MH.Id_device = "8" 满足设备上的条件。

但是假设还有其他字段没有显示,那么让我们重写:

SELECT MR.*
    FROM meter_relevation AS MR
    JOIN meter AS M ON ( M.Id = MR.ID_Meter )
    JOIN meter_history AS MH ON ( MH.Id_Meter = M.Id )
    JOIN device AS D ON ( D.Id=MH.Id_Device AND D.Id = "8" )
WHERE 
    MR.Date BETWEEN "2012-10-04" AND "2012-10-04";

所以我们需要索引。第一个最重要

CREATE INDEX mr_ndx     ON meter_relevation ( Date, Id_Meter );

但也尝试删除上面的索引并改用:

CREATE INDEX mr_ndx     ON meter_relevation ( Id_Meter, Date );


CREATE INDEX m_ndx      ON meter(Id); -- This probably already exists
CREATE INDEX mh_ndx     ON meter_history( Id_Device, Id_Meter );
CREATE INDEX d_ndx      ON device (Id); -- This too probably already exists

如果这样写,上面的代码等同于(但 MySQL 应该意识到这一点,所以我认为它不会减慢你太多)

SELECT MR.*
    FROM meter_relevation AS MR
    JOIN meter AS M ON ( MR.ID_Meter = M.Id)
    JOIN meter_history AS MH ON (MH.Id_Device = "8" AND MH.Id_Meter = M.Id)
WHERE 
    MR.Date BETWEEN "2012-10-04" AND "2012-10-04";

关于mysql - 缓慢的 MySQL SELECT 性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12729907/

相关文章:

php - 如何在完成 php fetch 后在第 1 行启动 while 循环

MySQL 查找和替换未按预期工作(序列化数据)

mysql - 只保留 SQL 数据库中的前 50 条记录并删除其余记录

database - 无法登录 Oracle Enterprise Manager Express

mysql删除语法错误

php - 是否存在与 PDO::FETCH_CLASS 相反的对象或将对象映射回数据库中

mysql - MySQL 8.x 中的主要错误? -- 外键

python - 创建测试数据库时,从现有数据库中复制所有数据。 Django

database - 在cakephp 2.x甚至函数中将数据保存在数据库中

php - 从 PHP 和 MySQL 的 3 个随机数据中选择 4 列