2010-08-20 82 views
2

进出口运行波纹管查询,以便从3个MySQL表获取和它的作品不错,但它增加了内存使用情况和某个需要10秒钟来启动加载页面mysql内部连接语句和内存过度使用!

INNER JOIN table_tags AS ntg ON (ns.tags = '' OR CONCAT(' ',COALESCE(ns.tags,' '),' ') LIKE CONCAT('% ',ntg.tid,' %')) 
    INNER JOIN table_topics AS nto ON (ns.associated = '' OR CONCAT(' ',COALESCE(ns.associated,'-'),' ') LIKE CONCAT('%',nto.topicid,'%')) 

问题在内部加入statemnet,如果我除去

ns.tags = '' OR

ns.associated =“” OR

内存过度使用问题将是固定的,但空标签字段

着演出的故事是没有办法写波纹管语句包括所有其他任何方式甚至那些没有标签的故事!?

INNER JOIN table_tags AS ntg ON (ns.tags = '' OR CONCAT(' ',COALESCE(ns.tags,' '),' ') LIKE CONCAT('% ',ntg.tid,' %')) 

我的标签ID存储在table_ns像(14 17 2)空间seprated

回答

1

你的条件ns.tags = '' OR ...意味着如果ns.tags = ''是真的从table_stories该记录将与所有在记录中加入table_tags。与ns.associated = '' OR ..相同。这可以很容易地“创建”huuuge结果集,这很可能不是你想要的。
如果你真的不想/不能改变/正常化的表结构(如你在评论说我以前的答案)我最好的猜测是使用两个LEFT JOINs像:

SELECT 
    ns.*, 
    ntg.tid, 
    nto.topicid, 
    group_concat(DISTINCT ntg.tag) as mytags, 
    group_concat(DISTINCT ntg.slug) as tagslug, 
    group_concat(DISTINCT nto.topicname) as mytopics, 
    group_concat(DISTINCT nto.slug) as topicslug, 
    ns.counter AS counter_num 
FROM 
    table_stories AS ns 
LEFT JOIN 
    table_tags AS ntg 
ON 
    CONCAT(' ', ns.tags,' ') LIKE CONCAT('% ',ntg.tid,' %') 
LEFT JOIN 
    table_topics AS nto 
ON 
    CONCAT(' ', ns.associated, ' ') LIKE CONCAT('%',nto.topicid,'%') 
WHERE 
    time <= '4711' 
GROUP BY 
    ns.sid 
ORDER BY 
    ns.sid DESC,ns.hotnews DESC 

但是MySQL不能使用这个索引,所以查询会导致全表扫描。它还需要临时表和文件夹,即查询相对较慢。
不改变表结构但数据从1 2 31,2,3格式,你至少可以得到使用稍快FIND_IN_SET(str, strlist)摆脱Concat()LIKE


只是为了保持完整性和万一你改变主意:http://en.wikipedia.org/wiki/Database_normalization