New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve performance of total_count for grouped queries #979
Improve performance of total_count for grouped queries #979
Conversation
0f16250
to
642b535
Compare
Thanks for the PR - I should be able to look into this next week (I'm taking an OSS time off). Also you don't have to worry about the failing tests as they should be fixed upstream. |
Thanks! |
Actually, the test failures look legit. I'll look into them to see if there's a quick fix. |
I have no idea why the master build is green, but if it's green, then good. Maybe there was something odd in Travis. |
When querying a subtype on a STI table, a 'hard scope' is applied that is incompatible with the use of `model.from(subquery)` This fix removes any type restriction from the _outer_ query (because the subquery already has the restriction). Introduced by kaminari#979
…or_grouped_queries" This reverts commit b5e2e07, reversing changes made to d1c26fd. We merged #979 as a performance improvement, but it turns out it introduced a couple of bugs. The solution seems to be a little tricky as it has to call `.unscoped` and `unscope(where: :type)`, so let's revert it until we find a better solution. closes #1012, #1015.
Sadly I had to revert this commit: 04d86ed as it introduced a couple of bugs. The workaround seems a bit tricky as it has to call I still like this PR though. I added a few tests from #1012 and #1015 so next time we try we should be able to catch bugs early. |
I'd like to add my +1 for this PR. Between this, #1012 and #1015, I do believe it's a good performance optimisation for larger result sets. In my opinion it's just ActiveRecord's syntax that makes it look hacky, c.model.unscoped.unscope(where: :type).from(c.except(:select).select("1")).count but actually we're just ensuring that the outer query is unpolluted with AR cleverness while the inner query I'd really like to see a commit which rebuilds this solution with all the accompanying tests. |
Well, first of all: Oopsy 😅 I'm gonna try to find a bit of time to play around with arel to solve this one, as I believe it should make it easier to write a query that won't be contaminated by default conditions added to the model. |
Of course! We only need the total count so that's a great idea to use arel to solve this. |
Thanks to everyone for their efforts so far. Is there a roadmap for the next release or could this be released as a patch 1.2.1? |
@ChrisBAshton It would be great if you could give the master branch a try and see if there is any issue with that. I haven't run into this issue personally so it's a bit difficult to make sure it's fixed. We should be able to cut a release once we are confident about this. |
@ChrisBAshton Thanks for reporting. It seems like your app is open-source, so I should be able to look into it on my free time. In the mean time, it would be great if you could share example code or test and the error you are seeing. |
@yuki24 just following up on this - I work with @ChrisBAshton. I've tested this against the current master branch (04d86ed), and the issue appears to be resolved 🎉. Hopefully there will be a patch version soon 🙏. In case it's helpful, the issue we're seeing is the same as the one in this PR. In our case:
I agree that #1012 would have been a surprise for us, and reverting the original cause of the bug seems like the best approach for now 👍. |
We're experiencing the exact same problem as @benthorner and @ChrisBAshton. Is there a plan to release that reversion to rubygems any time soon? |
We've just talked about cutting a new version soon. Stay tuned and thanks for your patience! |
Improved performance for total_count on grouped ActiveRecord::Relation. This re-implements kaminari#979 using Arel to avoid issues kaminari#1012 and kaminari#1015
Improved performance for total_count on grouped ActiveRecord::Relation. This re-implements kaminari#979 using plain SQL to avoid issues kaminari#1012 and kaminari#1015
Improved performance for total_count on grouped ActiveRecord::Relation. This re-implements kaminari#979 using Arel to avoid issues kaminari#1012 and kaminari#1015
@MmKolodziej I took your idea to rewrite it in Arel and ran with it, came up with #1022. I then realised that Arel was overkill and so I've turned-in a plain SQL version too, #1023, which is easier on the eye (and brain!) 🤞 hoping one of these solutions will make it in. |
Improved performance for total_count on grouped ActiveRecord::Relation. This re-implements kaminari#979 using plain SQL to avoid issues kaminari#1012 and kaminari#1015
Arel solves things beyond just constructing the query. It allows the statement to continue to be prepared. When we cast active record with
|
@kitsunde made a very good point. Based on this I also think the Arel solution is better. |
It's definitely a better solution. While I'm relatively familiar with Arel I'm not familiar with What I would want to know is:
Because if 2 doesn't happen, then repeat execution will just split the overhead and make it worse than raw SQL. |
Improved performance for total_count on grouped ActiveRecord::Relation. This re-implements kaminari#979 using Arel to avoid issues kaminari#1012 and kaminari#1015
@kitsunde to answer your questions:
Anyway, I closed #1023 because it clearly didn't smell right to anyone, and have updated #1022 in response to @guigs's comments. |
I think unscoped.unscope(:where).from(c.except(:select).select('1')).count would be a good solution. |
Code for #978.
SQL query will return a single count instead of forcing AR to serialize a hash which entries will be counted.