【问题标题】:How to execute query in and get count of total elements without running twice with Rails 4 and MySQL如何在不使用 Rails 4 和 MySQL 运行两次的情况下执行查询并获取总元素数
【发布时间】:2016-02-19 06:05:45
【问题描述】:

我正在 MySQL 和 Rails 中运行成本时间查询。此查询是动态创建的,它还使用LIMITOFFSET 管理分页。这是一个总结的例子:

SELECT fields
FROM tables
WHERE conditions
ORDER BY order DESC LIMIT ? OFFSET ?

我还想获取元素的总数,但出于性能目的,我想避免两次运行查询。我不认为这是可能的,但也许你让我感到惊讶:)

目前,我有类似的东西:

objects = Object.find_by_sql(query)    
totalCount = objects.count 

但是,当然,这总是返回限制计数。

【问题讨论】:

    标签: mysql ruby-on-rails


    【解决方案1】:

    因为您使用的是分页和偏移,所以您不会得到完整的结果。您可以运行两个单独的查询,也可以提取完整的数据集,然后过滤分页。第一个选项可能会更快,尤其是随着数据集的增长。

    为了提高性能,您可以在不同点查看缓存策略以获得更好的结果。在不知道数据何时发生变化的情况下,我无法提供任何具体建议。

    编辑 1:展开澄清

    这可能有助于解释为什么会这样。当您手动设置限制和偏移量时,Rails 对查询未返回的数据一无所知。因此,如果没有可用的数据,绝对不可能让 Rails 知道总数。

    也就是说,一个简单的COUNT 聚合应该总是非常快地执行。如果您在执行该查询时发现速度问题,您需要确保您有正确的索引,并且 Rails 正在以最佳格式呈现条件。

    【讨论】:

    • 我认为解决方案是运行两次查询。一种带有字段和限制(分页),另一种只有计数且没有限制。
    • 这绝对是最快的选择,对吧?但是检查正在生成的条件。虽然由于 Rails 处理事物的性质,它的可能性要小得多,但我已经看到 SAS 和 Oracle 在条件涉及函数时消除了主要的性能问题。
    【解决方案2】:

    MySQL?为什么不将 SQL_CALC_FOUND_ROWS 与 FOUND_ROWS() 一起使用?

    有两个查询:(第二个查询不会命中数据库)

    SELECT SQL_CALC_FOUND_ROWS * FROM users LIMIT 0,5;
    SELECT COUNT(FOUND_ROWS()) AS rows_count FROM users;
    

    但有一个建议:您必须对其进行测试。这可能比两个查询慢或快,这取决于一些因素,如缓存、引擎、索引等......

    https://dev.mysql.com/doc/refman/5.7/en/information-functions.html#function_found-rows

    Is this possible to get total number of rows count with offset limit

    【讨论】:

      【解决方案3】:

      要计算记录,只需将一个查询作为一列添加到您动态创建的查询中。

      检查一下:

      SELECT fields,(SELECT count(*) FROM tables WHERE conditions) as obj_count
      FROM tables
      WHERE conditions
      ORDER BY order DESC LIMIT ? OFFSET ?
      

      使用 MySQL 会话变量(以符号 @ 开头)我们可以编写更高效的查询。

      SELECT fields,@count as obj_count 
      FROM tables,(SELECT @count:=count(*) FROM tables WHERE conditions) as sub
      WHERE conditions
      ORDER BY order DESC LIMIT ? OFFSET ?
      

      【讨论】:

      • 我很好奇子选择是否是正确的方法,那不是对返回的每条记录运行计数查询吗?
      • 我想另一种选择是将数据集对象加入到您自己使用计数数据生成的查询中。但是我也很好奇 Rails 是如何渲染一个对象的,如果它得到了意想不到的列。查看find_by_sql,它似乎只包含与返回的模型相关的列。
      • 如果您阅读了该问题,您会发现我们正在努力寻找解决方案以获得最佳性能。
      • @Rober:检查更新后的查询,它比前一个查询更有效,因为它一次计算对象而不是所有行。
      • @Code-Monk 仍然不清楚记录是如何被实例化的......?
      【解决方案4】:

      这有点晚了,但请尝试使用 objects.length。长度将计算您在数组中已有的内容。

      【讨论】:

        猜你喜欢
        • 2021-06-17
        • 2015-02-11
        • 1970-01-01
        • 1970-01-01
        • 2015-05-07
        • 2021-11-18
        • 1970-01-01
        • 2017-08-03
        • 2018-01-06
        相关资源
        最近更新 更多