需要帮助来优化查询

时间:2013-05-23 14:06:49

标签: mysql query-optimization

有人可以帮我优化以下查询吗?它用于搜索将在自动完成表单中使用的搜索词和结果数据。数据将以JSON(可能)或HTML()的形式发送。但就目前而言,我担心的是如何优化此查询。网站上每天将有大约20000名用户(可能全部同时),我希望尽可能地优化这一点。

有些人可能已经猜到了,这些都是Drupal表,我正在生成一个自定义查询。

    EXPLAIN SELECT n.nid AS nid, fcs.field_call_sign_value AS field_call_sign_value, old.field_r_13_n_old_value AS field_r_13_n_old_value,
            new.field_r_13_n_new_value AS field_r_13_n_new_value,fn.field_name_value AS field_name_value
        FROM node n
            INNER JOIN field_data_field_call_sign fcs ON n.nid = fcs.entity_id and n.vid=fcs.revision_id
            INNER JOIN field_data_field_name fn ON n.nid = fn.entity_id and n.vid=fn.revision_id
            INNER JOIN field_data_field_r_13_n_old old ON n.nid = old.entity_id and n.vid=old.revision_id
            INNER JOIN field_data_field_r_13_n_new new ON n.nid = new.entity_id and n.vid=new.revision_id
        WHERE  (n.title LIKE '%APTNHD%' ESCAPE '\\') 
        ORDER BY n.created DESC
        LIMIT 5 OFFSET 0

解释结果:

id  select_type table   type    possible_keys           key             key_len ref     rows    Extra
1   SIMPLE      fcs     ALL     entity_id,revision_id   NULL            NULL    NULL    11  Using temporary; Using filesort
1   SIMPLE      old     ALL     entity_id,revision_id   NULL            NULL    NULL    11  Using where; Using join buffer
1   SIMPLE      new     ALL     entity_id,revision_id   NULL            NULL    NULL    11  Using where; Using join buffer
1   SIMPLE      fn      ALL     entity_id,revision_id   NULL            NULL    NULL    11  Using where; Using join buffer
1   SIMPLE      n       eq_ref  PRIMARY,vid PRIMARY 4   DB.new.entity_id                1   Using where

如果您需要更多信息,请与我们联系

编辑:“Stephan”回答后的新EXPLAIN结果 原始查询占用“0.0010秒”(多次执行时相同) 新查询花了“0.0012秒”(再次运行后为“0.0007秒”)

id  select_type table   type    possible_keys           key         key_len ref         rows    Extra
1   SIMPLE      n       ALL     NULL                    NULL        NULL    NULL        44      Using where; Using filesort
1   SIMPLE      fcs     ref     entity_id,revision_id   entity_id   4       DB.n.nid    1   
1   SIMPLE      fn      ref     entity_id,revision_id   entity_id   4       DB.n.nid    1   
1   SIMPLE      old     ref     entity_id,revision_id   entity_id   4       DB.n.nid    1   
1   SIMPLE      new     ref     entity_id,revision_id   entity_id   4       DB.n.nid    1   

1 个答案:

答案 0 :(得分:1)

mysql查询优化器决定切换表连接的顺序,以便扫描的行数较少,但并非在所有情况下这都是好的。

我看到,对于已加入的表,您在entity_id上有索引,这很好,因此您需要使用STRAIGHT_JOINLEFT JOIN来维护联接表顺序:

EXPLAIN SELECT STRAIGHT_JOIN n.nid AS nid, fcs.field_call_sign_value AS field_call_sign_value, old.field_r_13_n_old_value AS field_r_13_n_old_value,
            new.field_r_13_n_new_value AS field_r_13_n_new_value,fn.field_name_value AS field_name_value
        FROM node n
            LEFT JOIN field_data_field_call_sign fcs ON n.nid = fcs.entity_id and n.vid=fcs.revision_id
            LEFT JOIN field_data_field_name fn ON n.nid = fn.entity_id and n.vid=fn.revision_id
            LEFT JOIN field_data_field_r_13_n_old old ON n.nid = old.entity_id and n.vid=old.revision_id
            LEFT JOIN field_data_field_r_13_n_new new ON n.nid = new.entity_id and n.vid=new.revision_id
        WHERE  (n.title LIKE '%APTNHD%' ESCAPE '\\') 
        ORDER BY n.created DESC
        LIMIT 5 OFFSET 0

此外,您可以在FULLTEXT INDEX列上添加n.title,因为您可以fulltext-searchs使用比(n.title LIKE '%APTNHD%' ESCAPE '\\')

更快的{{3}}