【问题标题】:Sorting records quickly from a model with 500k records从具有 50 万条记录的模型中快速排序记录
【发布时间】:2013-04-28 18:25:32
【问题描述】:

我正在尝试对包含 500k 行的模型中的记录进行排序。当我最初尝试此过程时,我只有 200 条记录,并使用以下代码并提取了 1-5 条记录以列出最受欢迎的记录:

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

但是,现在我有一个更大的数据集,这会使我的计算机停止运行,我希望尝试以更有效的方式完成搜索。

我已尝试将代码调整为@mostpopular = Product.order('click_count DESC').limit(10),但这仍然需要很长时间才能完成...

有没有更有效的方法从大型数据集中提取前 10 条最受欢迎的记录?

感谢您的宝贵时间

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 sqlite activerecord database-performance


    【解决方案1】:

    答案很可能不在 Rails 中,而是在您的数据库中。

    将查询写入日志,以便查看正在执行的查询:

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

    一旦您掌握了 SQL,请转到数据库的控制台并要求它向您显示该查询的查询计划和统计信息。你没有说你正在使用什么数据库,但在 postgresql 中,你会使用 EXPLAIN 命令。我会看到正在进行的行扫描(又名序列扫描)。

    您可能会发现click_count 缺少索引,添加它可以解决您的问题。

    【讨论】:

    • 感谢您如此迅速地回复。我只是使用 Rails 中内置的 sqllite3 数据库。过去我在让控制台运行时遇到了麻烦,但我会搜索说明并查看它这次是否正常工作。感谢您的帮助,让您了解问题所在非常有用
    【解决方案2】:

    首先根据您的系统或服务器配置设置排序缓冲区大小。同样对于 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")
    

    查看上述查询的效率或时间消耗。

    【讨论】:

    • OP 在我的回答中提到数据库是 sqllite3
    【解决方案3】:

    您只需添加索引即可提高查询速度。将以下内容添加到migration

    add_index :products, :click_count
    

    然后运行rake db:migrate

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-06
      • 2011-07-06
      • 1970-01-01
      • 1970-01-01
      • 2013-09-25
      • 2012-01-16
      相关资源
      最近更新 更多