2016-09-16 8 views
0

を制限するよりも小さいとき、私は550.000記録MySQLのスロークエリの結果は

SELECT * FROM logs WHERE user = 'user1' ORDER BY date DESC LIMIT 0, 25 

でテーブルをしたこのクエリは0.0171秒かかります。 LIMITなしでは、3537の結果があります。

SELECT * FROM logs WHERE user = 'user2' ORDER BY date DESC LIMIT 0, 25 

このクエリには3.0868秒かかります。

PRIMARY KEY (`id`), 
KEY `date` (`date`) 

"LIMIT 0,25" 25未満のレコードが存在する場合、クエリが遅くを使用している場合:LIMITなしで、13件の結果

テーブルのキーがあるがあります。どうすればこの問題を解決できますか?

+0

テーブルにインデックスを作成しましたか?'LIMIT'もちょうど25でなければなりません。私は0が何をしているのか分かりません。 –

+1

これは[この質問](http://stackoverflow.com/questions/13846691/adding-limit-clause-to-mysql-query-slows-it-datatically)と似ているかもしれませんが、本質的にそれが問合せオプティマイザからの索引の選択が間違っています。 'explain'でそれをチェックしようとすると、あなたの質問に[index hints](http://dev.mysql.com/doc/refman/5.7/en/index-hints.html)を付けて修正することができます。 – makadev

+1

@MikeTung 'LIMIT 0,25'は* OFFSET * * LIMIT *の略です。これは単純に 'レコード0から始まる25個のレコードを意味します。 ' – makadev

答えて

1

limit 25を使用すると、25行が見つかったときにクエリを停止できます。

あなたは550.000のうち、3537の一致する行を持っている場合、それは、平均的に、均等分布を仮定し、dateによって注文されたリスト(date上のインデックス)、またはあるリストに550.000/3537*25 rows = 3887 rowsを調査した後、25行を発見しただろう全く注文されていません。

550.000のうち一致する行が13個ある場合、limit 25はすべて550.000行(141行の行数)を調べなければならないため、0.0171 sec * 141 = 2.4sと予想しています。明らかにランタイムを決定する他の要因もありますが、大きさの順序は適合します。

追加の効果があります。残念ながら、dateのインデックスにはuserの値が含まれていないため、MySQLは元のテーブルでその値を参照する必要があります(データ自体は主キーによって順序付けされるため)。これは、順序付けられていない表を直接読み取るよりも遅くなります。

実際、インデックスを使用するよりも、インデックスを使用するよりも速くなる可能性があります。あなたは、MySQLを強制的に使用しないようにすることができます。 FROM logs IGNORE INDEX (date)がありますが、これはすべての場合にテーブル全体を読み取らなければならないという効果があります。dateで注文したため、最後の行が最新であり、結果セット内になければなりません。したがって、最初のクエリが遅くなる可能性があります。高速550.000行を読み込むと、前後にジャンプして3887行をゆっくりと読み込むよりも遅くなる可能性があります。 (MySQLは事前にこのことを知っていないので、2番目のクエリが間違っていることは明らかです)。

どのように高速な結果を得るには?

userで注文されるインデックスがあります。 'user2'のクエリは、それ以上行がないことを知っているので、13行後に停止することができます。そして、これは'user1'のクエリよりも速くなり、3537行を見てから、後でdateで順序を変えなければなりません。

それでは、それ以上の行を探すのをやめて、リストが既に望むように注文されている(そしてすべての場合に0.0171を打ち負かす)ことを知っているので、クエリの最良のインデックスはuser, dateです。

インデックスにはリソースが必要です(たとえば、テーブルを更新するときにインデックスを更新するためのhddスペースと時間)ので、すべてのクエリに完全なインデックスを追加すると、システム全体では時々逆効果になることがあります。