私はORDER BY RAND()とそのパフォーマンスの問題について読んだことがあります。これらは大きなデータセットを返すクエリにのみ適用されますか?たとえば、100,000行のテーブルがあり、WHERE句を使用して10個のレコードを含むデータセットを返し、ORDER BY RAND()LIMIT 1を使用すると、テーブルがフィルタリングされた後にこのORDER BY RAND()が適用されます。 WHERE句に一致するレコードがあるため、パフォーマンス上の問題はごくわずかです。MySQL ORDER BY RAND()はいつ機能しますか?
答えて
そうだね、それが持つ行の数、GROUP BYを減らし、およびHAVINGの後、ORDER BYを適用します。ただし、LIMITの前にORDER BYを適用します。
したがって、十分な数の行をフィルタリングすると、ORDER BY RAND()はパフォーマンスに大きな影響を与えることなく、目的の値を達成できます。シンプルで読みやすいコードには正当な利益があります。
あなたのクエリでは、行が何か小さいものになるはずですが、データが大きくなるにつれて、並べ替える必要がある行の数が再び大きくなるという問題が発生します。あなたのクエリは、並べ替えられた結果のLIMIT 10は、500k行でORDER BY RAND()を実行しているという事実を隠しています。あなたは不思議なほどパフォーマンスが悪化しているのを見ているだけです。
私は私の本SQL Antipatterns: Avoiding the Pitfalls of Database Programmingで、またはスタックオーバーフロー上、ここで他の回答にランダムな行を取り出すための代替方法について書かれています:
あなたの答えと矛盾する2つの他のポスターは、WHERE句に関係なくテーブルのすべての行に対して常に乱数を生成します。私自身のテストに基づいて、あなたの答えは正解でした。ありがとう!私の場合は、データベーステーブルの小さなサブセットからランダムな行が必要です。 – key2starz
Bill、これを読んだら、2つのクエリのテクニックについてここで読んでいます:http://stackoverflow.com/questions/3558665/randomizing-large-dataset/3558919#3558919私の場合、複数のクエリを使用する必要がありますジョインなどがあります。このテクニックはその場合も機能しますか? – key2starz
RAND()
の値は各行ごとに計算されるため、大きなデータセットの場合はそれほど効率的ではありません。LIMIT
句はそれを変更しません。この問題を回避する一般的な方法は、あらかじめ乱数を計算し、あらかじめ生成されたインデックス付きの列に基づいてそれに対応する行を取得することです。あなたが選択する行数は問題ではありません
:
は、ここに1つの詳細な説明です。 ORDER BY RAND()
の場合、テーブル内のすべての単一の行に対して乱数が計算されます。これは、どの行が最大値を生成したのかを知るためには、各行のランダム値を計算する必要があるからです。したがって、100,000行のテーブルがあり、ORDER BY RAND() LIMIT 1
を呼び出すと、100,000行の乱数を生成し、その数でソートしてから最初のものを与えるようにMySQLに指示します。
SELECT COUNT(*)
Table
からあなたのスクリプト/プログラミング言語で0と上記のクエリの結果マイナス1の間の乱数を生成します:それははるかに高速にある
。
Table
LIMITのrandom_number_here FROMSELECT *、1
をクイックテストに基づいて、ORDER BY RAND()が適用されるのはの後に WHEREステートメントが適用され、データセット全体に適用されるわけではありません。 50,000行を持つ表から
結果:わずかなデータセットを扱う場合
SELECT * FROM `mytable` LIMIT 1 (1 total, Query took 0.0007 sec)
SELECT * FROM `mytable` WHERE First = 'Hilda' LIMIT 1 (1 total, Query took 0.0010 sec)
SELECT * FROM `mytable` WHERE First = 'Hilda' (142 total, Query took 0.0201 sec)
SELECT * FROM `mytable` WHERE First = 'Hilda' ORDER BY RAND() LIMIT 1 (1 total, Query took 0.0229 sec)
SELECT * FROM `mytable` WHERE First = 'Hilda' ORDER BY RAND() (142 total, Query took 0.0236 sec)
SELECT * FROM `mytable` ORDER BY RAND() LIMIT 1 (1 total, Query took 0.4224 sec)
- 1. MySQL DISTINCTはGROUP BYタイムスタンプでは機能しません
- 2. MYSQLなぜORDER BY DESCは失敗しますが、ORDER BY ASCは機能しますか?
- 3. GROUP BYは機能しません
- 4. GROUP BYはどのように機能しますか?
- 5. ORDER BY RAND()はUNION内では機能しません
- 6. R機能は
- 7. Rヘルプ - /または機能?
- 8. 私はRに二つの機能を定義している
- 9. R機能はvarialbles
- 10. MySQLでSELECT DISTINCTはどのように機能しますか?
- 11. MySQL関連するクエリを持つ節が機能していません
- 12. このmysqlクエリはどのように機能しますか?
- 13. SQL DISTINCT/GROUP BYが機能していません
- 14. が、私はこのGET_ALL機能していPHP/MySQLの機能
- 15. MYSQLカウント機能
- 16. Mysql order by byエイリアス
- 17. RでsetTimeLimitはどのように機能しますか?
- 18. このRコードはどのように機能しますか?
- 19. mySQLグループクエリが機能しない
- 20. X.509証明書が入力されていませんDERに変換しても機能しません
- 21. mysqlクエリが機能しない
- 22. MySQL DELETEが機能しない
- 23. R、 "tm"パッケージ - エラー:コーパス機能が見つかりません
- 24. ORDER BY CASE句は次のコードでどのように機能しますか?
- 25. MySQL Left Joinクエリが機能しない
- 26. カット機能R
- 27. カバー機能(?):R
- 28. rローリングカスタム機能
- 29. R.機能。エラー
- 30. Rテキストオートメーション機能
事実上何でもすぐに行くことができますが、概念的にLIMITはORDER BY句の後に適用されます。つまり、クエリオプティマイザによって異なります。なぜテストDBで試してみませんか? –
以下の私の実験を参照してください。 - ORDER BY RAND()はWHERE句で返されたレコードのサブセットに適用されます - 143レコードを返すレコードセットの場合、ランダムレコードに制限すると、 where句を持たないテーブル全体にはかなり時間がかかりました。 – key2starz