我有这个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_id
int(11)NOT NULL auto_increment,cat_name
varchar(255)NOT NULL,alias
varchar(255)NOT NULL,title
varchar(255)NOT NULL,cat_desc
文本NOT NULL,cat_parent
int(11)NOT NULL默认为'0',cat_links
int(11)NOT NULL默认为'0',cat_cats
int(11)NOT NULL默认为'0',cat_featured
tinyint(4)NOT NULL默认为'0',cat_image
varchar(255)NOT NULL,cat_published
tinyint(4)NOT NULL默认为'0',cat_created
datetime NOT NULL默认'0000-00-00 00:00:00',cat_approved
tinyint(4)NOT NULL默认为'0',cat_template
varchar(255)NOT NULL default'',cat_usemainindex
tinyint(4)NOT NULL默认为'0',cat_allow_submission
tinyint(4)NOT NULL默认值为'1',cat_show_listings
tinyint(3)unsigned NOT NULL默认值为'1',metakey
文本NOT NULL,metadesc
文本NOT NULL,ordering
int(11)NOT NULL默认为'0',lft
int(11)NOT NULL默认为'0',rgt
int(11)NOT NULL默认为'0', PRIMARY KEY(cat_id
), KEYcat_id
(cat_id
,cat_published
,cat_approved
), KEYcat_parent
(cat_parent
,cat_published
,cat_approved
,cat_cats
,cat_links
), KEYdtree
(cat_published
,cat_approved
), KEYlft_rgt
(lft
,rgt
), KEYfunc_getPathWay
(lft
,rgt
,cat_id
,cat_parent
), KEYalias
(alias
) )ENGINE = MyISAM AUTO_INCREMENT = 3851 DEFAULT CHARSET = utf8 |
j25_mt_links架构:
CREATE TABLE
j25_mt_links
(link_id
int(11)NOT NULL auto_increment,link_name
varchar(255)NOT NULL,alias
varchar(255)NOT NULL,link_desc
mediumtext NOT NULL,user_id
int(11)NOT NULL默认为'0',link_hits
int(11)NOT NULL默认为'0',link_votes
int(11)NOT NULL默认为'0',link_rating
十进制(7,6)无符号NOT NULL默认值'0.000000',link_featured
smallint(6)NOT NULL默认为'0',link_published
tinyint(4)NOT NULL默认为'0',link_approved
int(4)NOT NULL默认为'0',link_template
varchar(255)NOT NULL,attribs
文本NOT NULL,metakey
文本NOT NULL,metadesc
文本NOT NULL,internal_notes
文本NOT NULL,ordering
int(11)NOT NULL默认为'0',link_created
datetime NOT NULL默认'0000-00-00 00:00:00',publish_up
datetime NOT NULL默认'0000-00-00 00:00:00',publish_down
datetime NOT NULL默认'0000-00-00 00:00:00',link_modified
datetime NOT NULL默认'0000-00-00 00:00:00',link_visited
int(11)NOT NULL默认为'0',address
varchar(255)NOT NULL,city
varchar(255)NOT NULL,state
varchar(255)NOT NULL,country
varchar(255)NOT NULL,postcode
varchar(255)NOT NULL,telephone
varchar(255)NOT NULL,fax
varchar(255)NOT NULL,website
varchar(255)NOT NULL,price
double(9,2)NOT NULL默认值'0.00',lat
float(10,6)NOT NULL COMMENT'Latitude',lng
float(10,6)NOT NULL评论'经度',zoom
tinyint(3)unsigned NOT NULL COMMENT'Map'的缩放级别', PRIMARY KEY(link_id
), KEYlink_rating
(link_rating
), KEYlink_votes
(link_votes
), KEYlink_name
(link_name
), KEYpublishing
(link_published
,link_approved
,publish_up
,publish_down
), KEYcount_listfeatured
(link_published
,link_approved
,link_featured
,publish_up
,publish_down
,link_id
), KEYcount_viewowner
(link_published
,link_approved
,user_id
,publish_up
,publish_down
), KEYmylisting
(user_id
,link_id
), FULLTEXT键link_name_desc
(link_name
,link_desc
) )ENGINE = MyISAM AUTO_INCREMENT = 3229 DEFAULT CHARSET = utf8 |
j25_mt_cfvalues架构:
CREATE TABLE
j25_mt_cfvalues
(id
int(11)NOT NULL auto_increment,cf_id
int(11)NOT NULL,link_id
int(11)NOT NULL,value
mediumtext NOT NULL,attachment
int(10)unsigned NOT NULL默认为'0',counter
int(11)NOT NULL默认为'0', PRIMARY KEY(id
), KEYcf_id
(cf_id
,link_id
), KEYlink_id
(link_id
), KEYvalue
(value
(8)) )ENGINE = MyISAM AUTO_INCREMENT = 20876 DEFAULT CHARSET = utf8 |
答案 0 :(得分: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)