当前位置: 首页 > 知识库问答 >
问题:

优化MySQL中的多连接

林烨烨
2023-03-14
select c.cat_id,c.cat_name as cat_name, 
 c.cat_desc, c.cat_image, mi.filename, 
 l.link_id, l.user_id, l.address,l.city, 
 l.country,l.link_created,l.link_desc, 
 l.email,l.fax,l.link_hits, l.link_modified,
 l.link_name,l.postcode, l.price,l.link_rating, 
 l.state,l.telephone,l.link_votes,
 l.website, l.link_id, l.link_visited, cf.value
from j25_mt_cats as c,
j25_mt_links as l 
LEFT OUTER JOIN j25_mt_cfvalues AS cf ON (cf.link_id = l.link_id),
j25_mt_images AS mi,
j25_mt_cl as cl
UNION ALL
select c.cat_id,c.cat_name as cat_name, 
 c.cat_desc, c.cat_image, mi.filename, 
 l.link_id, l.user_id, l.address,l.city, 
 l.country,l.link_created,l.link_desc, 
 l.email,l.fax,l.link_hits, l.link_modified,
 l.link_name,l.postcode, l.price,l.link_rating, 
 l.state,l.telephone,l.link_votes,
 l.website, l.link_id, l.link_visited, cf.value
FROM j25_mt_cats as c,
j25_mt_links as l
RIGHT OUTER JOIN j25_mt_cfvalues AS cf ON cf.link_id = l.link_id,
j25_mt_images AS mi,
j25_mt_cl as cl
where cf.cf_id = 40 and cl.link_id = l.link_id 
 AND mi.link_id = l.link_id AND mi.ordering < 2  
 AND c.cat_id = cl.cat_id and c.cat_published = 1 
 AND c.cat_approved = 1 and l.link_published = 1 and l.link_approved = 1
 AND cf.link_id IS NULL;

该查询占用了tmp目录中的3GB+并最终超时。我这里少了点什么,怎样才能提高效率?我在这里的目标只是添加到现有查询中,以便从额外的表(j25_mt_cfvalues)中获取值。

解释:

+----+--------------+------------+-------+---------------+---------+---------+--------------------------+------+------------------+
| id | select_type  | table      | type  | possible_keys | key     | key_len | ref                      | rows | Extra            |
+----+--------------+------------+-------+---------------+---------+---------+--------------------------+------+------------------+
|  1 | PRIMARY      | mi         | ALL   | NULL          | NULL    | NULL    | NULL                     |  165 |                  |
|  1 | PRIMARY      | c          | ALL   | NULL          | NULL    | NULL    | NULL                     |  301 |                  |
|  1 | PRIMARY      | l          | ALL   | NULL          | NULL    | NULL    | NULL                     | 2139 |                  |
|  1 | PRIMARY      | cf         | ref   | link_id       | link_id | 4       | db_table.l.link_id |    2 |                  |
|  1 | PRIMARY      | cl         | index | NULL          | PRIMARY | 4       | NULL                     | 2742 | Using index      |
|  2 | UNION        | NULL       | NULL  | NULL          | NULL    | NULL    | NULL                     | NULL | Impossible WHERE |
| NULL | UNION RESULT | <union1,2> | ALL   | NULL          | NULL    | NULL    | NULL                     | NULL |                  |
+----+--------------+------------+-------+---------------+---------+---------+--------------------------+------+------------------+

j25_mt_cats模式:

共有1个答案

白翰海
2023-03-14

问题是,您的第一个SQL查询没有任何WHERE条件,并在您正在处理的每个表中造成全局笛卡尔。只有在第二个查询中才应用WHERE子句。

也就是说,CF表有一个左联接和右联接,但不能同时有CF=40和CF为NULL,所以我简化为只有ID和40的左联接...因此,如果CF表中有一条记录,它只显示它的值是40...任何其他值都将被忽略。

也就是说,您的查询可以简化为一个查询。我还更改了连接语法,而不是哪里,这样您和其他人就可以看到与表的关系,而不是猜测。

select 
      (all your fields)
   from 
      j25_mt_cats as c
         JOIN j25_mt_cl as cl
            ON c.cat_id = cl.cat_id 
            JOIN j25_mt_links as l 
               ON cl.link_id = l.link_id 
               AND l.link_published = 1 
               AND l.link_approved = 1
               JOIN j25_mt_images AS mi
                 ON l.link_id = mi.link_id 
                AND mi.ordering < 2  
                LEFT OUTER JOIN j25_mt_cfvalues AS cf 
                   ON l.link_id = cf.link_id
                   AND cf.cf_id = 40
   where
          c.cat_published = 1 
      AND c.cat_approved = 1 
   ORDER BY 
      RAND() DESC;
j25_mt_cats should have an index on (cat_published, cat_approved)
j25_mt_cl on (cat_id)
j25_mt_links on (link_id, link_published, link_approved)
j25_mt_images on (link_id, ordering)
j25_mt_cfvalues on (link_id, cf_id)
 类似资料:
  • 下面说的优化基于 MySQL 5.6,理论上 5.5 之后的都算适用,具体还是要看官网 服务状态查询 查看当前数据库的状态,常用的有: 查看系统状态:SHOW STATUS; 查看刚刚执行 SQL 是否有警告信息:SHOW WARNINGS; 查看刚刚执行 SQL 是否有错误信息:SHOW ERRORS; 查看已经连接的所有线程状况:SHOW PROCESSLIST; 查看当前连接数量:SHOW

  • 在整体的系统运行过程中,数据库服务器 MySQL 的压力是最大的,不仅占用很多的内存和 cpu 资源,而且占用着大部分的磁盘 io 资源,连 PHP 的官方都在声称,说 PHP 脚本 80% 的时间都在等待 MySQL 查询返回的结果。由此可见,提高系统的负载能力,降低 MySQL 的资源消耗迫在眉睫。 常见优化方法: 1、页面缓存 1、页面缓存功能是降低MySQL的资源消耗的(PHPCMS V9

  • 优化MySQL左联接仍然有问题。该查询需要0.13秒才能完成,而下一个查询需要0.00秒(简化)。 对于该查询,我希望达到0.00左右。 解释输出: 现在,同样的简化查询运行良好(使用索引等,唯一的区别在于括号之间): 解释说:

  • 问题内容: 我的用户表有26列以上,这正常吗?当该用户表引起我注意时,数据库已被标准化为第3级。设计26列是否可以,或者在设计数据库时应该使用其他优化技术吗? 更多:对表进行分区是什么意思? 问题答案: 26列没有什么问题,但是如果很少使用它们,那就不一样了。 而不是使用26列,而是使用更少的列,并使用序列化字符串将它们分组。 将字段更改为文本字段,然后在代码中可以对它们进行反序列化并使用它们。如

  • 本文向大家介绍MySQL中对表连接查询的简单优化教程,包括了MySQL中对表连接查询的简单优化教程的使用技巧和注意事项,需要的朋友参考一下 在MySQL中,A LEFT JOIN B join_condition执行过程如下: · 根据表A和A依赖的所有表设置表B。 · 根据LEFT JOIN条件中使用的所有表(除了B)设置表A。 · LEFT JOIN条件用于确定如何从表B搜索行。(换句话说,不

  • 本文向大家介绍Mysql优化之Zabbix分区优化,包括了Mysql优化之Zabbix分区优化的使用技巧和注意事项,需要的朋友参考一下 使用zabbix最大的瓶颈在于数据库,维护好zabbix的数据存储,告警,就能很好地应用zabbix去构建监控系统。目前zabbix的数据主要存储在history和trends的2个表中,随着时间的推移,这两个表变得非常大,性能会非常差,影响监控的使用。对MySQ