1

有人可以帮我优化以下查询吗?它用于搜索将在自动完成表单中使用的搜索词和结果数据。数据将作为 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

如果您需要更多信息,请告诉我

编辑:“斯蒂芬”回答后的新解释结果 原始查询花费“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   
4

1 回答 1

1

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

我看到对于连接表,您的索引entity_id很好,因此您需要使用STRAIGHT_JOINand维护连接表顺序LEFT 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 INDEXonn.title列,因为这样您就可以使用更快的全文搜索(n.title LIKE '%APTNHD%' ESCAPE '\\')

于 2013-05-23T14:21:01.003 回答