2012-02-26 6 views
1

がここに私のクエリの速度と構造データに影響を与えると思わない:MySQLクエリに時間がかかります。私は、クエリの多くのバリエーションを試してみた、と何も、そのまま

SELECT * 
    FROM gmm_sql as a 
LEFT JOIN usds as b ON a.dp_id = b.dp_id 
LEFT JOIN usdsown as c ON b.dp_id = c.dp_id 
    WHERE a.comm like '%tree%' 
  • gmm_sql: 21フィールドを。すべてのフィールドvarchar()は20〜255の範囲で混在しています。4,882レコード。
  • usds: 7フィールド。すべてのフィールドvarchar()は20〜255の範囲で混在しています。304,713レコード。
  • usdsown:フィールド。すべてのフィールドvarchar()は20〜255の範囲で混在しています。107,606レコード。

私は手動で一致があることを確認しました。私はこれらのクエリテストを実行するためにMySQL Workbenchを使用しています。クエリはちょうど10分間実行し続け、停止しません...

私は何かを真剣にやっていますか?ここ

はEXPLAIN出力である:IDフィールドがインデックスされると仮定すると

id select_type table type possible_keys key key_len ref rows Extra 
1 SIMPLE a ALL NULL NULL NULL NULL 3973 Using where 
1 SIMPLE b ALL dp_id NULL NULL NULL 304345 
1 SIMPLE c ALL NULL NULL NULL NULL 105711 
+1

フィールドがすべてvar_charsの場合、それはおそらく良いデザインではありません。インデックスを作成しましたか? – Stevo

+0

質問に「EXPLAIN」の出力を添付してください:http://dev.mysql.com/doc/refman/5.0/en/explain.html – Mchl

+0

私はEXPLAINの出力を見ることから始めます。これらの結合は、それらのdp_id列に索引がない場合に非常に高価になります。 –

答えて

3

、これは潜在的に、依然として膨大なデータセットです。次に、varcharにワイルドカードを使用して最終的なwhere句を指定します。これにより、結果セット全体の完全なテーブルスキャンが行われ、a.commフィールドのインデックスが無効になります。

好奇心が強いですが、select *を 'select count(a.comm)'に変更してwhere句を削除することでテストできます。まだそれが永遠に続く場合はwhere句、それ以外の場合は結果セットの構築です。

2

make FULLTEXT index on gmm_sql.gmm。 +すべての外部キーがインデックスされていることを確認してください。

WHERE a.comm like '%tree%'は、データの中で最もコストがかかる操作です。あなたは文字通りフルテーブルスキャンを行う必要があります。一致順の先頭でにワイルドカードがあるので、通常のインデックスでは不十分です。データベースは、インデックスのこのタイプをサポートしていない場合

また、あなたはluceneのまたはスフィンクスを使用することができます。

2

私が見競合の最初のポイントは次のとおりです。あなたは、文字列の左側には、インデックスは役に立たなくワイルドカード、GMM_SQL.commにインデックスを持っている場合でも

WHERE a.comm like '%tree%' 

。これは機能しますが、データ型が文字列に関連するコンテンツを検索することは文字通り最悪の方法です。

フルテキスト検索(MySQL specific link)は、文字列内のコンテンツを検索するのに適した方法です。しかし、IIRC、MySQLはまだテーブルがMyISAMである必要があります...

次のポイントは次のとおりです。

SELECT * 

これはJOIN'dさすべてのテーブルからすべて列を返しています。列の1つが:IEを - あなたはあなたが本当にパフォーマンスでネジ止めすることができます

  • にデータ型を必要とするよりも多くのデータを返すしている

    1. :ので、SELECT句は、実際に必要な列が含まれている必要があります非常に長い文字列またはバイナリ/ BLOBデータです

    第3 - あなたのJOIN基準。データ型が小さいほどクエリは高速になります。私はidと何かを仮定するつもりですINTを意味します。必要がない場合はBIGINTを使用しないでください。

  • 関連する問題