新手问题 activerecord 用 find_by_sql 方法进行多表查询数据总是会出现一条 count 查询,如何去掉?(已解决)

zhq_zhq · 2014年11月06日 · 最后由 zhq_zhq 回复于 2014年11月06日 · 3518 次阅读

表之间的关系如下图

Product.paginate_by_sql("SELECT distinct products.* FROM products left JOIN product_prices ON product_prices.product_id =products.id left JOIN taggings ON taggings.other_id = products.id AND taggings.t_type='product' left JOIN sub_taggings ON sub_taggings.other_id = products.id AND sub_taggings.t_type='product' left JOIN brand_products ON brand_products.product_id = products.id where #{conditions} order by #{order_info}",:per_page=>28, :page=>page||1) 

下面是日志

19:39:10 DEBUG:   [1m[35mProduct Load (826.8ms)[0m  SELECT distinct products.* FROM products left JOIN product_prices ON product_prices.product_id = products.id left JOIN taggings ON taggings.other_id = products.id AND taggings.t_type='product' left JOIN sub_taggings ON sub_taggings.other_id = products.id AND sub_taggings.t_type='product' left JOIN brand_products ON brand_products.product_id = products.id where products.status=true order by products.is_top desc, products.is_recommend desc, products.rank desc, products.created_at desc LIMIT 28 OFFSET 0 
19:39:10 DEBUG:   [1m[36mEXPLAIN (15.6ms)[0m  [1mEXPLAIN SELECT distinct products.* FROM products left JOIN product_prices ON product_prices.product_id = products.id left JOIN taggings ON taggings.other_id = products.id AND taggings.t_type='product' left JOIN sub_taggings ON sub_taggings.other_id = products.id AND sub_taggings.t_type='product' left JOIN brand_products ON brand_products.product_id = products.id where products.status=true order by products.is_top desc, products.is_recommend desc, products.rank desc, products.created_at desc LIMIT 28 OFFSET 0[0m 
19:39:10 WARN: EXPLAIN for: SELECT distinct products.* FROM products left JOIN product_prices ON product_prices.product_id = products.id left JOIN taggings ON taggings.other_id = products.id AND taggings.t_type='product' left JOIN sub_taggings ON sub_taggings.other_id = products.id AND sub_taggings.t_type='product' left JOIN brand_products ON brand_products.product_id = products.id where products.status=true order by products.is_top desc, products.is_recommend desc, products.rank desc, products.created_at desc LIMIT 28 OFFSET 0
+----+-------------+----------------+------+-------------------------------------------------------------+------------------------------------+---------+-----------------+------+----------------------------------------------+
| id | select_type | table          | type | possible_keys                                               | key                                | key_len | ref             | rows | Extra                                        |
+----+-------------+----------------+------+-------------------------------------------------------------+------------------------------------+---------+-----------------+------+----------------------------------------------+
|  1 | SIMPLE      | products       | ref  | index_products_on_status                                    | index_products_on_status           | 2       | const           | 8627 | Using where; Using temporary; Using filesort |
|  1 | SIMPLE      | product_prices | ref  | index_product_prices_on_product_id                          | index_product_prices_on_product_id | 5       | qdd.products.id |    1 | Using index; Distinct                        |
|  1 | SIMPLE      | taggings       | ref  | index_taggings_on_t_type,index_taggings_on_other_id         | index_taggings_on_other_id         | 5       | qdd.products.id |    1 | Distinct                                     |
|  1 | SIMPLE      | sub_taggings   | ref  | index_sub_taggings_on_other_id,index_sub_taggings_on_t_type | index_sub_taggings_on_other_id     | 5       | qdd.products.id |    1 | Distinct                                     |
|  1 | SIMPLE      | brand_products | ref  | index_brand_products_on_product_id                          | index_brand_products_on_product_id | 5       | qdd.products.id |    1 | Using index; Distinct                        |
+----+-------------+----------------+------+-------------------------------------------------------------+------------------------------------+---------+-----------------+------+----------------------------------------------+
5 rows in set (0.03 sec)

19:39:12 DEBUG:   [1m[35mProduct Count (1497.6ms)[0m  SELECT COUNT(*) FROM (SELECT distinct products.* FROM products left JOIN product_prices ON product_prices.product_id = products.id left JOIN taggings ON taggings.other_id = products.id AND taggings.t_type='product' left JOIN sub_taggings ON sub_taggings.other_id = products.id AND sub_taggings.t_type='product' left JOIN brand_products ON brand_products.product_id = products.id where products.status=true ) AS count_table 
will_paginate 插件支持对数组进行分页

def paginate(options = {})
    page     = options[:page] || 1
    per_page = options[:per_page] || WillPaginate.per_page
    total    = options[:total_entries] || self.length

    WillPaginate::Collection.create(page, per_page, total) do |pager|
      pager.replace self[pager.offset, pager.per_page].to_a
 end


paginate 算总页数的时候需要用到 count。

@Rei 这个问题,有其他的解决办法吗?

#2 楼 @zhq_zhq 用的什么插件?

思路:看文档,有没有跳过 count 直接设置总数的接口,有的话缓存总数,查询的时候直接设置;没有话打补丁加个接口。

@Rei 用的是 will_paginate 插件,will_paginate 插件中好像有处理数组的方法

@Rei 谢谢你的解答!这个问题已经解决,will_paginate 支持数组分页

@Rei 谢谢你的解答!这个问题已经解决,will_paginate 支持数组分页

需要 登录 后方可回复, 如果你还没有账号请 注册新账号