我遇到了一个MySQL查询,需要2分钟才能完成,并且服务器负载非常高(例如从2到14,有时甚至更高)。
查询在表之间执行左连接,然后根据连接表的浮点列对数据进行排序,如下所示:
SELECT table1.*, table2.*, table3.field, table4.field
FROM table1
LEFT JOIN table2 ON table1...
LEFT JOIN table3 ON table1...
LEFT JOIN table4 ON table3...
LEFT JOIN table5 ON table1...
WHERE table1.deleted=0
ORDER BY table2.float_field ASC
LIMIT 1,300
JOINS全部在索引键上完成,table2在float_field上也有索引。
在没有问题的情况下,在其他数据库上使用相同的数据库结构和查询。这个table2是一个自定义字段表,可以由这个数据库的用户改变,所以在这个特定的系统中,我看到它有107个字段,其中超过2/3是varchar(150)。这是高负荷的原因,还是有其他原因?有关如何处理它的任何建议(理想情况下无需重新执行数据库模式)?
提前致谢。
编辑:以下是'解释'结果:
+----+-------------+--------+--------+---------------+---------+---------+-----------------+-------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+--------+---------------+---------+---------+-----------------+-------+-------------+
| 1 | SIMPLE | table1 | ALL | idx_1,idx_2 | NULL | NULL | NULL | 33861 | Using where |
| 1 | SIMPLE | table2 | eq_ref | PRIMARY | PRIMARY | 108 | db.table1.id | 1 | |
| 1 | SIMPLE | jtl0 | ref | idx_X | idx_X | 111 | db.table1.id | 1 | |
| 1 | SIMPLE | table4 | eq_ref | PRIMARY,... | PRIMARY | 108 | db.jtl0.field | 1 | |
| 1 | SIMPLE | jt1 | eq_ref | PRIMARY | PRIMARY | 108 | db.table1.fieldX| 1 | |
+----+-------------+--------+--------+---------------+---------+---------+-----------------+-------+-------------+
idx_1和idx_2都使用“已删除”列作为索引中的第一个字段。
中只有这一个字段我还更正了原文,有5个表使用,不是4个(虽然最后一个表只有20行,所以这里没关系。)
答案 0 :(得分:0)
select table2.*
通常是错误的样式 - 返回很多你不感兴趣的列。在这种情况下,由于此表中有大量(文本)列,它可能导致速度变慢。
100列* 150个字符* 1300行大约为19.5 MB,因此速度很慢可能是从磁盘读取所有数据并通过网络传输。
如果将此限制为您感兴趣的table2的特定列,是否仍然看到缓慢?
编辑:您的解释选择输出似乎确认运行起来不是一个困难的查询,只有少量行。这使得table2中每行的绝对数据大小成为最可能的问题。您可以通过删除/限制对table2的引用来测试它。如果是这种情况,那么加快此查询速度的唯一方法是从table2请求更少的列。