ご質問は、データベースクエリは何とかO(n)
であるという仮定に基づいている - 彼らはありません(そうでないJOIN
sが恐ろしく高価です)。
SQLは、リレーショナル代数に基づいたRDBMシステムに存在するテーブル/ローストアの抽象化であり、参照も請求もしません。実行時の複雑さは良いです。これは、インプリメンテーション・データベース・システムがインデックス、インメモリー・ストア、特殊ケース・ハンドラーおよびその他の最適化を使用してさまざまなランタイム・パフォーマンスで正しい結果を提供できるためです。これは、SQLが物理行番号、ブロックアドレス、Bツリーノードなどの実装の詳細を公開していないことを意味します。クエリを書くときには、これらのことに気を付けるべきではありません。大事なのは、あなたの質問。
したがって、特にスマートなDBMSにはORDER BY RANDOM() LIMIT 1
の特殊ケースハンドラがあり、これはO(1)
の時間に実行されます。
...しかし、このケースではMySQLが最適化されていないようですので、より良いアプローチが必要です。 clustered_indexex_column
があなたの主キーまたは上ORDER BY
を実行することが非常に安くなってそれ以外の列かもしれコラムです
SELECT @n := COUNT(*) FROM table_name
SET @offset := ROUND(RAND() * @n)
SELECT * FROM table_name ORDER BY clustered_indexed_column LIMIT 1 OFFSET @offset
:
はこれを試してみてください。インデックスが正しく設定されていると仮定すると、このクエリはO(log(n))
以上の順に実行されます。
出典
2016-10-26 22:58:33
Dai
あなたが投稿したクエリが 'O(あなたが投稿したクエリが' n) '(where n == rowcount')time? – Dai
アルゴリズムR https://en.wikipedia.org/wiki/Reservoir_samplingはO(N)演算でランダムタプルを選ぶことができますが、どのDBMSでも実装されていません与えられたNとordinaの存在を考えるとl列はbtreeインデックスの場合はO(log(N))、ハッシュインデックスの場合はO(1)に減らされます。 – wildplasser
@Dai:質問していただきありがとうございます。 'EXPLAIN'には、「ランダムなキーで並べ替える」ことが言及されています。これは文字通り取ったもので、言及した最適化の種類を除外しているようですが、おそらく方法があります。 'EXPLAIN'の出力は一般的にパフォーマンスの良い指針ですか? –