2

50 万行のモデルでレコードを並べ替えようとしています。最初にこの手順を試みたとき、レコードは 200 しかありませんでした。次のコードを使用し、レコード 1 ~ 5 を引き出して、最も人気のあるレコードをリストしました。

@mostpopular = Product.find(:all, :order => 'click_count DESC')

しかし、今でははるかに大きなデータセットがあり、これによりコンピューターが停止してしまい、より効率的な方法で検索を完了しようとしています.

コードを調整してみまし@mostpopular = Product.order('click_count DESC').limit(10)たが、完了するまでに長い時間がかかります...

大規模なデータセットから最も人気のある上位 10 件のレコードを効率的に抽出する方法はありますか?

御時間ありがとうございます

4

3 に答える 3

1

答えはおそらくレールではなく、データベースにあります。

クエリをログに書き込むと、実行中のクエリを確認できます。

logger.debug Product.find(:all, :order => 'click_count DESC').limit(10).to_sql

SQL を手に入れたら、データベースのコンソールに向かい、そのクエリのクエリ プランと統計を表示するように依頼します。使用しているデータベースはわかりませんが、postgresql では EXPLAIN コマンドを使用します。行スキャン (別名シーケンススキャン) が行われていることがわかります。

インデックスが見つからない場合click_countは、インデックスを追加すると問題が解決します。

于 2013-05-04T12:37:10.860 に答える
1

クエリの速度を向上させるには、インデックスを追加するだけです。以下をmigrationに追加します。

add_index :products, :click_count

次に実行しますrake db:migrate

于 2013-05-04T12:56:53.093 に答える
0

システムまたはサーバーの構成に従って、最初にソートバッファサイズを設定します。また、MySQL ルート ディレクトリにある my.ini ファイルの内容を編集します。

[client]
#password   = your_password
port        = 3306
socket      = /tmp/mysql.sock

# The MySQL server
[mysqld]
port        = 3306
socket      = /tmp/mysql.sock
skip-external-locking
key_buffer_size = 16K
max_allowed_packet = 1M
table_open_cache = 4
sort_buffer_size = 64K
read_buffer_size = 256K
read_rnd_buffer_size = 256K
net_buffer_length = 2K
thread_stack = 128K

sort_buffer_sizeこのリンクhttp://www.mysqlperformanceblog.com/2007/08/18/how-fast-can-you-sort-data-with-mysql/を参照して設定することでパフォーマンス を向上させると、アプリケーションのパフォーマンスが向上します。

Product.find_by_sql("SELECT * FROM products ORDER BY click_count DESC LIMIT 10")

上記のクエリで消費される効率または時間を参照してください。

于 2013-05-04T12:54:27.630 に答える