1

我有这个应该是正确语法的 MySQL:

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) 中获取值。

explain

+----+--------------+------------+-------+---------------+---------+---------+--------------------------+------+------------------+
| 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 模式:

CREATE TABLE j25_mt_cats( cat_idint(11) NOT NULL auto_increment, cat_namevarchar(255) NOT NULL, aliasvarchar(255) NOT NULL, titlevarchar(255) NOT NULL, cat_desctext NOT NULL, cat_parentint(11) NOT NULL default '0', cat_linksint(11 ) NOT NULL 默认 '0', cat_catsint(11) NOT NULL 默认 '0', cat_featuredtinyint(4) NOT NULL 默认 '0', cat_imagevarchar(255) NOT NULL, cat_publishedtinyint(4) NOT NULL 默认 '0', cat_createddatetime NOT NULL 默认值 '0000-00-00 00:00:00', cat_approvedtinyint(4) NOT NULL 默认值 '0', cat_templatevarchar(255) NOT NULL 默认值 '', cat_usemainindextinyint(4) NOT NULL 默认值 '0', cat_allow_submissiontinyint(4 ) NOT NULL 默认为 '1', cat_show_listingstinyint(3) unsigned NOT NULL default '1', metakeytext NOT NULL, metadesctext NOT NULL, orderingint(11) NOT NULL default '0', lftint(11) NOT NULL default '0', rgtint(11) NOT NULL default ' 0', PRIMARY KEY ( cat_id), KEY cat_id( cat_id, cat_published, cat_approved), KEY cat_parent( cat_parent, cat_published, cat_approved, cat_cats, cat_links), KEY dtree( cat_published, cat_approved), KEY lft_rgt( lft, rgt), KEY func_getPathWay( lft, rgt, cat_id, cat_parent), KEY alias( alias) ) ENGINE=MyISAM AUTO_INCREMENT=3851 默认字符集=utf8 |

j25_mt_links 架构:

CREATE TABLE j25_mt_links( link_idint(11) NOT NULL auto_increment, link_namevarchar(255) NOT NULL, aliasvarchar(255) NOT NULL, link_descmediumtext NOT NULL, user_idint(11) NOT NULL default '0', link_hitsint(11) NOT NULL default '0' , link_votesint(11) NOT NULL 默认'0', link_ratingdecimal(7,6) unsigned NOT NULL 默认'0.000000', link_featuredsmallint(6) NOT NULL 默认'0', link_publishedtinyint(4) NOT NULL 默认'0', link_approvedint( 4) NOT NULL 默认 '0', link_templatevarchar(255) NOT NULL, attribstext NOT NULL, metakeytext NOT NULL, metadesctext NOT NULL, internal_notestext NOT NULL, orderingint(11) NOT NULL default '0', link_createddatetime NOT NULL 默认 '0000-00-00 00:00:00', publish_updatetime NOT NULL 默认 '0000-00-00 00:00:00', publish_downdatetime NOT NULL 默认 '0000-00-00 00:00:00' , link_modifieddatetime NOT NULL default '0000-00-00 00:00:00', link_visitedint(11) NOT NULL default '0', addressvarchar(255) NOT NULL, cityvarchar(255) NOT NULL, statevarchar(255) NOT NULL, countryvarchar(255) NOT NULL, postcodevarchar(255) NOT NULL, telephonevarchar(255) NOT NULL, faxvarchar(255) NOT NULL, emailvarchar(255) NOT NULL, websitevarchar(255) NOT NULL, pricedouble(9,2) NOT NULL默认 '0.00', latfloat(10,6) NOT NULL COMMENT '纬度', lngfloat(10, 6) NOT NULL COMMENT '经度',zoomtinyint(3) unsigned NOT NULL COMMENT '地图'的缩放级别', PRIMARY KEY ( link_id), KEY link_rating( link_rating), KEY link_votes( link_votes), KEY link_name( link_name), KEY publishing( link_published, link_approved, publish_up, publish_down), KEY count_listfeatured( link_published, link_approved, link_featured, publish_up, publish_down, link_id), KEY count_viewowner( link_published, link_approved, user_id, publish_up, publish_down), KEY mylisting( user_id, link_id), FULLTEXT KEY link_name_desc( link_name, link_desc) ) ENGINE=MyISAM AUTO_INCREMENT=3229 DEFAULT CHARSET=utf8 |

j25_mt_cfvalues 模式:

CREATE TABLE j25_mt_cfvalues( idint(11) NOT NULL auto_increment, cf_idint(11) NOT NULL, link_idint(11) NOT NULL, valuemediumtext NOT NULL, attachmentint(10) unsigned NOT NULL default '0', counterint(11) NOT NULL default '0 ', 主键 ( id), 键cf_id( cf_id, link_id), 键link_id( link_id), 键value( value(8))) ENGINE=MyISAM AUTO_INCREMENT=20876 默认字符集=utf8 |

4

1 回答 1

2

问题是您的第一个 SQL 查询没有任何 WHERE 条件,并且在您正在工作的每个表中导致全局笛卡尔。只有在第二个查询中才会应用 WHERE 子句。

也就是说,您对 CF 表有一个左连接和右连接,但是您不能同时拥有 cf=40 和 cf IS NULL,所以我简化为 ID 和 40 上的左连接......所以如果有是 CF 表中的一条记录,仅在其值为 40 时才显示...任何其他值都将被忽略..

也就是说,您的查询可以简化为单个查询。我还更改为 JOIN 语法而不是 WHERE,以便您和其他人可以看到与表的关系与猜测。

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)
于 2013-09-30T02:46:28.600 回答