2011-01-20 7 views
13

クエリに結合があり、2つのインデックスを使用しているように見えるため、より複雑になります。私はこれを改善することができるかどうか分からないが、私は頼むと思った。私は正しいインデックスを持っているのか、MySQLのクエリの速度を上げることができないのか分かりません。

クエリは、クエリされているレコードと同様のキーワードを持つレコードのリストを生成します。

ここに私の質問です。

SELECT match_keywords.padid, 
     COUNT(match_keywords.word) AS matching_words 
FROM keywords current_program_keywords 
     INNER JOIN keywords match_keywords 
     ON match_keywords.word = current_program_keywords.word 
WHERE match_keywords.word IS NOT NULL 
     AND current_program_keywords.padid = 25695 
GROUP BY match_keywords.padid 
ORDER BY matching_words DESC 
LIMIT 0, 11 

alt text

WordはVARCHAR(40)で説明しています。あなたは、次のフィールド(該当するものを表にチェック)

をインデックスmatch_keyword.padidすべき

+0

明確化:あなたが似て言うが、あなたのクエリで使用すると、match_keywords.word = current_program_keywords.word' ON '使用は、両方の単語が同じであることを意味します。レコード#の25695.word = 'aaa'さて、もし、クエリが単語=' aaa' ... GROUP BYとORDER BYはどんな意味がありませんを持っている 'N'行を返します。 'n'はあなたが興味を持っている唯一の変数ですか? –

+0

同様、年のそれは、できるだけ多くの単語と一致し、最もマッチの数を提供して、その上でソートすると、最も類似したレコードを提供します。 – Jules

答えて

9

フィールドでCOUNTによって暗黙的に削除されたIS NOT NULLテストを削除しようとすることで開始できます。また、から25695を省略すると思われます。それ以外の場合は、25695(またはその他)が11行の制限内で「最も良い」一致として表示されますか?

SELECT  match_keywords.padid, 
      COUNT(match_keywords.word) AS matching_words 
FROM  keywords current_program_keywords 
INNER JOIN keywords match_keywords 
     ON match_keywords.word = current_program_keywords.word 
WHERE  current_program_keywords.padid = 25695 
GROUP BY match_keywords.padid 
ORDER BY matching_words DESC 
LIMIT  0, 11 

次に、人としてどのように行うかを検討してください。

    あなたはpadid(25695)で始まり、そのpadid単語のものをリストから
  • ためのすべての単語を検索し、再びテーブルに行くと一致する各単語のために、 を取得する場合と
  • そのpadidさん( padidの一緒のグループ
  • padid + wordに重複がないものと仮定し、それらに
  • 順序数をカウントし、3 SEPAのリストでは最高11

を返します最初の2つのステップ(両方とも2つの列のみを含む)は、他の列を取得するために常に索引からデータにジャンプする必要があります。インデックスを覆うことここに助けるかもしれない - 彼らはこれら2によって覆われているので、代わりにこれらの複合インデックスで

create index ix_keyword_pw on keyword(padid, word); 
create index ix_keyword_wp on keyword(word, padid); 

をテストするために、2つの複合インデックスを作成し、あなたはpadidwordに単一列索引を削除することができます。

注:あなたは常にインデックスの

  • サイズ(より多くのあなたが店に多くを作成する)
  • 挿入/もはやそれが取る更新パフォーマンス(複数のインデックスに対するSELECTパフォーマンスを和らげるために持っていますデータを更新してからコミットしてからすべてのインデックスを更新する必要があります)
+0

EXPLAIN表が示すように、人は必ずしもオプティマイザが意志の方法ではないとして、あなたがそれを行うような方法を持っています選択する;私は間違いなく、純粋なロジックとは正反対の方法で、SQL Serverが鉱山の簡単なクエリを処理していることを覚えています。 – pascal

+0

しかし、私は適切にEXPLAIN読めば、我々はpadid、単語、単語/ padidの数をよりよく理解する必要があるだろうという方向にさらに行くために...、25695のために、我々は8つのワードを取得し、唯一の5行は、これら8に一致します言葉...おそらく平均的な場合ではないでしょう。 – pascal

+1

推論に誤りがあります。暗黙COUNT'によって除去される '削除されていないNULLテストは、IS NOT NULLが冗長正しいされていない起因内側に' match_keywords.word = current_program_keywords.word'に参加します –

1

match_keyword.words

current_program_keywords.words

希望をcurrent_program_keywords.padidそれは加速するのに役立ちます

+0

キーワードと呼ばれる1つのテーブル。 – Jules

+0

は、私は言葉にインデックスを持っていると – Jules

+0

をpadidだから私は本当に –

5

次のようにしてください。PadIDのインデックスとWORDのインデックスを確認してください。次に、SELECT WHERE修飾子の順序を変更して、CURRENTキーワードのPADIDを最初に最適化し、次に他のものに結合します。結合自体を除外します。また、あなたが内部に平等にチェックされて以来、一致キーワードに参加...現在のキーワードはnullをチェックされている場合、それはすべての比較を見ているようので、MATCHキーワードの別名に比較なくし、ヌル値に参加することはありませんNULLを探していると...必要

SELECT STRAIGHT_JOIN 
     match_keywords.padid, 
     COUNT(*) AS matching_words 
    FROM 
     keywords current_program_keywords 
     INNER JOIN keywords match_keywords   
      ON match_keywords.word = current_program_keywords.word 
      and match_keywords.padid <> 25695 
    WHERE 
      current_program_keywords.padid = 25695 
     AND current_program_keywords.word IS NOT NULL 
    GROUP BY 
     match_keywords.padid 
    ORDER BY 
     matching_words DESC 
    LIMIT 
     0, 11 
関連する問題