2017-02-09 10 views
0

例:ビジター(ボットなど)を検出するデータベースがあり、すべての訪問者が同じ資格を持っているわけではないので、私は 'ダイナミック'テーブルを作成しました:fiddle:http://sqlfiddle.com/#!9/ca4c8/1 )。MySQLの自己結合パフォーマンス:事実か不正なインデックス作成ですか?

これは、私が(別のDB内の)各プロファイルに関する情報を収集するために使用するプロファイルIDを返します。プロフィールのタイプに応じて、別のname句(名前= '何か')(ei:ホスト名、ipAddr、userAgent、HumanIdなど)を使用してテーブルを検索します。

私はSQLの専門家ではないが、私は、インデックス、制約、主、ユニーク、外部キーなどを持つと私はこれらの検索結果から見たものから、よく知っている:

それらのほとんどは悪い自己結合のパフォーマンスが、不足しているインデックス原因のために行く傾向がある回答についてコメントを持っています。

最終的な質問は次のとおりです。テーブルに自己結合すると、すべてが適切にインデックスされていると仮定すると、パフォーマンスが悪化しやすくなります。サイドノート、テーブルの詳細情報に


:質問とは無関係であるかもしれないが、私の特定の状況のコンテキストでもある:

  • 列フラグがとして削除のレコードをマークするために使用されます私がPHPから使用しているユーザは、このデータベースに対してDELETEパーミッションを持っていません。申し訳ありませんが、セキュリティはパフォーマンスよりも重要です
  • 私は、ユーザーエージェントから取得した情報を使用する 'タイプ'を追加しました。 (つまり、少なくともボットと思われるものがあれば、タイプ5000を検索します。
  • 'name'カラムは残念なことに主キー(プロファイルとタイプ)でインデックスされています。
  • 私は多くのINTとフィルタリング(WHERE)をSELECTクエリで使用して、最終的なパフォーマンスの低下を軽減しました(問題があったとしても)
  • バックグラウンドの高い人が必要であれば、

これは私が開発している大きなプロジェクトですので、何百万ものレコードでテストすることはできませんが、私はperformanこれが成長するにつれて、ceは問題になるでしょう。入力、リンク、リファレンス、ドキュメンテーションまたはテスト手順(コメントの可能性があります)は高く評価されます。

答えて

1

自己結合は、2つの異なるテーブルを結合することと同じです。オプティマイザは、通常、WHEREに基づいて1つの 'テーブル'を選択し、次にネストループジョインを他のものに行います。あなたの場合、LEFTを介して、それは片方向でしか動作しないことを暗示しています。 (オプティマイザはを無視します。が必要ない場合は無視します。

あなたのキーは、そのフィドルのためにあります。

本当の問題は、テーブルにデータをレイアウトする面倒な方法である「Entity-Attribute-Value」です。あなたのクエリは、特定の属性のペア(name = Googlebot AND addr = ...)を持つ「見つからない(制限1)profile(エンティティ)」と思われるようです。

これははるかに簡単で、 2列(名前とADDR)と「複合」INDEX(name, addr)

を持っている私は共通ための「属性」は、JSON文字列を持つ単一の列に残りを入れていること。hereを参照してください。

ことをお勧めします
+0

私は2つの列を使用しなかった理由は、異なる種類のプロファイルが異なる必要があるということです。属性の量。 (ei:apisには4:name、addr、appid、tokenが必要です)。 –

+0

"自己結合は、2つの異なるテーブルを結合することと同じです。"あなたのプロフィールを見ると、私はこれを解決したものとしてタグ付けするような衝動を感じています。 –

関連する問題