2012-04-21 10 views
3

私はMySQLに2つのテーブルを持っていますが、table1には1,013,347のエンティティと38の属性があり、table2には7,343,905のエンティティと10の属性があります。次のクエリ(ページングの行数を取得する予定)では、table1.IDはPK、table2.IDはFK(どちらもインデックス付けされている)、HAVING句は特定のパーセンテージを超える場合に値を取得しますこの場合、50%MySQLクエリが非常に遅い

SELECT SQL_CALC_FOUND_ROWS * 
FROM table1 INNER JOIN table2 ON table1.ID = table2.ID 
WHERE table1.attribute1 LIKE 'D%' 
GROUP BY table2.ID 
HAVING (COUNT(table2.ID) * (100/18)) >= '50' 

でさえ、私はここに掲載簡素化状態では、このクエリは、コマンドラインから実行することなしには5分未満かかります。私はクエリ、PHPコード(値 '50'と 'D'はPHP変数を介して割り当てられます)、および/またはMySQLの設定に変更を加える必要があることを知っています。最新のXAMPPとデフォルト設定)。どんな助けでも大歓迎です。

EDIT1:すべての属性は、VARCHAR(9)のID属性を除いてTINYTEXTです。

EDIT2:SELECT ...リターンを説明します。ここでは

+----+-------------+--------+------+---------------+-------------+---------+------+---------+---------------------------------+ 
| id | select_type | table | type | possible_keys | key   | key_len | ref | rows | Extra       | 
+----+-------------+--------+------+---------------+-------------+---------+------+---------+---------------------------------+ 
| 1 | SIMPLE  | table2 | ALL | NULL   | NULL  | NULL | NULL | 7343905 | Using temporary; Using filesort | 
| 1 | SIMPLE  | table1 | ref | ID   | ID   | 29  | func |  1 | Using where      | 
+----+-------------+--------+------+---------------+-------------+---------+------+---------+---------------------------------+ 
2 rows in set (0.00 sec) 
+2

'EXPLAIN SELECT ...'と表示されたらどうなりますか? –

+1

パフォーマンスには影響しませんが、数字を引用することはありません。 '' 50'''、それは結局あなたを上回ります。プラス義務的なコーディングホラー[「ページネーションは死んでいる」参照](http://www.codinghorror.com/blog/2012/03/the-end-of-pagination.html)。 – Ben

+3

table1を索引付けしましたか?attribute1、これに対してあなたは 'LIKE'をしていますか? – Marc

答えて

3

は、いくつかの改善の可能性あり:

  • あなたがタイプVARCHAR(9)のIDを使用していて、perfomingしているこれらのフィールドを使用して参加します。結合を高速化するために、varcharsの代わりに整数代理キーを導入することをお勧めします。 this discussionを参照してください。
  • LIKE演算子は通常高価です。あなたの使い方を考えてください。 Marcのように、table1.attribute1にインデックスを付ける必要があります。
  • 「LIKE」を省略すると、「D%」の代わりにRIGHT()を使用してクエリを高速化することができますが、それがはるかに高速かどうかはわかりません。テーブル内のデータが頻繁に変更されない場合は、事前にカットされたtable1.attribute1値が1つずつ追加された新しいインデックス付きカラムを作成できます。しかし、それはどの値がPHPスクリプトによってLIKEの後に挿入されるかによって異なります。パフォーマンスを向上させる
1

いくつかのアイデア

  1. インデックスtable2.ID(必要)とtable1.IDすぎ
  2. 可能であれば、ID列がvarchar型のBIGINTとtable1.attribute1します。 、列
  3. ではなく、SQL(18分の100)の内部で計算を行うの推定データ長に基づいて、varchar列のための適切なサイズを定義世話をする(COUNT(table2のを有する本

    ようにそれを交換してください.ID)*(5.5555))> = 50

(table2.IDは今BIGINTであることから、数学的な比較は若干速くなければならない)

私が見るように、のような句は、上で重要ですこのようなクエリは、たとえ高価なものであっても、table1.attribu te1も同様です。

これが役に立ちます

+0

'attribute1'のインデックスは' like'節を高速化しますか? – Kos

関連する問題