1

Drupal ビューを高速化するために MySQL クエリを最適化しようとしています。

テーブルは node、term_node、および term_data です。ノードには約 50 万行、term_node には約 80 万行、term_data には約 30 万行があります。

クエリの下:

    SELECT SQL_NO_CACHE DISTINCT(node.nid) AS nid
    FROM drupal_node node
    LEFT JOIN drupal_term_node term_node ON node.vid = term_node.vid
    LEFT JOIN drupal_term_data term_data ON term_node.tid = term_data.tid 
    WHERE (node.status = 1) AND (node.type in ('foto_foto')) 
    AND (
      (UPPER(term_data.name) LIKE UPPER('%Hanaa%') OR 
      UPPER(term_data.name) LIKE UPPER('%Bouchaib%')))
    GROUP BY nid
    LIMIT 0, 10;

このクエリは、結果を表示するのに約 11 秒かかります。結合に含まれるすべての列と、term_data.name に索引が付けられます。node.vid、term_node.vid、term_node.tid、term_data.tid は int(10)、term_data.name は varchar(255) です。

奇妙なことは、次のような構成クエリを実行することです。

SELECT SQL_NO_CACHE DISTINCT(term_node.tid)
FROM drupal_term_data term_data
LEFT JOIN drupal_term_node term_node ON term_node.tid = term_data.tid 
WHERE ((UPPER(term_data.name) LIKE UPPER('%Hanaa%') 
  OR UPPER(term_data.name) LIKE UPPER('%Bouchaib%')))
group by term_node.tid

SELECT SQL_NO_CACHE DISTINCT(node.nid) AS nid
FROM drupal_node node
LEFT JOIN drupal_term_node term_node ON node.vid = term_node.vid
WHERE (node.status = 1) AND (node.type in ('foto_foto')) 
GROUP BY nid

最初に 0.23 秒、最後に 0.12 秒かかります。したがって、メイン クエリは少なくとも 0.5 秒未満で実行されるはずです。オプティマイザーがクエリで実行されていないようです。

関連するテーブルで既に ANALYZE と OPTIMIZE を実行しました。以下は EXPLAIN EXTENDED の結果です。

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: node
         type: range
possible_keys: vid,node_status_type,node_type
          key: node_status_type
      key_len: 102
          ref: NULL
         rows: 496217
     filtered: 100.00
        Extra: Using where
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: term_node
         type: ref
possible_keys: PRIMARY,vid
          key: vid
      key_len: 4
          ref: drupal_foto.node.vid
         rows: 7
     filtered: 100.00
        Extra: Using where
*************************** 3. row ***************************
           id: 1
  select_type: SIMPLE
        table: term_data
         type: eq_ref
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 4
          ref: drupal_foto.term_node.tid
         rows: 1
     filtered: 100.00
        Extra: Using where
3 rows in set, 1 warning (0.00 sec)

この警告は、コード 1003 のノート レベルの警告のみを提供します。

4

1 に答える 1

1

私は結果を保証しますが、試してみるべきことがいくつかあります:

  1. クエリには term_data に対する比較フィルターがあるため、左結合を使用するべきではありません。左結合を内部結合に変更します。これは、それぞれの両方のテーブルの行のみを返すためです。これにより、テーブルという用語を最初に使用できるようになります。

  2. Distinct と group by は冗長です。両方はいらないはずです。どちらかを使用してください。

于 2012-06-16T23:35:00.910 に答える