如何优化mysql查询?

时间:2014-07-15 06:22:52

标签: mysql sql

此查询需要很长时间才能执行。有谁告诉我如何优化这个查询?

SELECT distinct(node.nid) AS nid ,
       CAST((LENGTH(node_data_field_pdfextract.field_pdfextract_value) - LENGTH(REPLACE(LOWER(node_data_field_pdfextract.field_pdfextract_value) , 'test', ''))) / LENGTH('test') AS UNSIGNED ) AS name_match ,
       node.title AS node_title,
       node_data_field_first_name.field_cj_article_author_name_value,
       node_data_field_first_name.field_first_name_value
FROM ram_node node
LEFT JOIN
  (SELECT td.tid,
          tn.vid AS revision
   FROM ram_term_data td
   INNER JOIN ram_term_node tn ON tn.tid = td.tid
   WHERE td.vid IN (12,
                    15,
                    14)) term_data_node ON node.vid = term_data_node.revision
LEFT JOIN ram_content_type_cj_article node_data_field_first_name ON node.vid = node_data_field_first_name.vid
LEFT JOIN ram_node_revisions node_revisions ON node.vid = node_revisions.vid
LEFT JOIN ram_term_node term_node ON node.vid = term_node.vid
LEFT JOIN ram_term_data term_data ON term_node.tid = term_data.tid
LEFT JOIN ram_content_field_pdfextract node_data_field_pdfextract ON node.vid = node_data_field_pdfextract.vid
LEFT JOIN ram_uc_products uc_products ON node.vid = uc_products.vid
WHERE (node.status = 1)
  AND (node.type IN ('cj_article'))
  AND ((UPPER(node_revisions.body) LIKE UPPER('%test%'))
       OR UPPER(node_data_field_pdfextract.field_pdfextract_value) LIKE UPPER('%test%'))
  AND (UPPER(node.title) LIKE UPPER('%%'))
ORDER BY name_match DESC;

1 个答案:

答案 0 :(得分:0)

阶段1,删除所有不必要的连接。您只在select子句和where子句中使用node和node_data_field_pdfextract。

第2阶段,因为你在where子句中引用了node_data_field_pdfextract,所以在该表上使用左连接没有任何意义,请使用效率更高的INNER JOIN。

第3步,真的需要明确吗?它需要大量资源。如果不需要摆脱它。

第4步,是否在where子句中需要使用UPPER()?将函数应用于字段时,在该字段上使用任何索引都会被拒绝,导致在大多数情况下进行全表扫描。如果可能的话,不要使用这些功能。考虑将数据存储在UPPER中并将其编入索引。

步骤1,2& 3:

SELECT
      node.nid                                                                                                            AS nid
    , CAST((LENGTH(node_data_field_pdfextract.field_pdfextract_value) 
     - LENGTH(REPLACE(LOWER(node_data_field_pdfextract.field_pdfextract_value), 'test', ''))) / LENGTH('test') AS UNSIGNED) AS name_match
    , node.title                                                                                                            AS node_title
    , node_data_field_first_name.field_cj_article_author_name_value
    , node_data_field_first_name.field_first_name_value
FROM ram_node node
      INNER JOIN ram_content_field_pdfextract node_data_field_pdfextract
                  ON node.vid = node_data_field_pdfextract.vid
WHERE node.status = 1
      AND node.type IN ('cj_article')
      AND (
             UPPER(node_revisions.body) LIKE UPPER('%test%')
            OR 
             UPPER(node_data_field_pdfextract.field_pdfextract_value) LIKE UPPER('%test%')
           )
      AND UPPER(node.title) LIKE UPPER('%%')
ORDER BY
      name_match DESC;

顺便说一下 SELECT distinct(node.nid)

解析器忽略了这些括号。 区别不是功能

DISTINCT符合SELECT(即考虑" SELECT DISTINCT"作为一对单词) 加:

SELECT DISTINCT是"行操作符&#34 ;;它在行的所有部分执行,当然不仅仅是放在括号中的字段。

我建议你停止使用这些括号,因为它让你觉得它做的事情根本不会做。