Skip to content
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

Inner join visible orders #4879

Merged

Conversation

sauloperez
Copy link
Contributor

@sauloperez sauloperez commented Mar 2, 2020

What? Why?

Improves (but doesn't close yet) #4782.

This replaces the underlying SQL to get the visible orders, which has quite far-reaching consequences as this bit of logic controls which orders a user can see in reports. Instead of using LEFT JOIN we use INNER JOIN. This means we won't load all line_items, variants and products of the DB but only the ones that match the line_items that belong to the specified orders.

This has an immediate effect on the time it takes to get the data from the DB. On staging data, goes from this complex query plan which reports 2.46s of execution time to this other query plan. This time the execution drops to 1.04s with a reduction (very likely but I haven't checked) on RAM usage.

What should we test?

We should test the distributor totals by supplier report but also at least two other reports. I'd say the ones enterprises use the most but I can only guess. My bet is:

  • Packing
  • Order cycle management

Release notes

Build reports reducing the pressure on the DB by refactoring a permissions SQL query.
Changelog Category: Changed

@@ -0,0 +1,249 @@
require 'spec_helper'

describe Spree::Admin::ReportsController, type: :controller do
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to mimic the report I generated with sample data in staging. All of it without shortcuts so I managed to control all the data involved, which enabled me to understands all the bits and pieces of the report generation. I don't plan to keep after I finally close the issue. Meanwhile, it provides the lab conditions necessary to iterate quickly.

Copy link
Contributor

@luisramos0 luisramos0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, I think this is ok and will improve things 👍
Inner joins are generally faster than left joins 👍

I dont think your explanation is correct though:
"This means we won't load all line_items, variants and products of the DB but only the ones that match the line_items that belong to the specified orders."
The only entries that will not be loaded now are orders without line items AND orders with line items without variants AND orders with line items with variants without products. This is why I think this will not create any trouble.

if create_csv
@csv_report = csv_report(header, table)
send_data @csv_report, filename: csv_file_name
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

from "rapper style" code to "daily language" code ❤️

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note however that my whole point was to introduce an ivar (which I absolutely dislike) so I could test the csv output. I wanted to avoid any test mocks if possible.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, I see, much better anyway!

@@ -82,8 +82,7 @@ def scale_factor(product)
end

def order_permissions
return @order_permissions unless @order_permissions.nil?
@order_permissions = ::Permissions::Order.new(@user)
@order_permissions ||= ::Permissions::Order.new(@user)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and from "dumb style" to "eloquent style" ❤️

@sauloperez
Copy link
Contributor Author

Yeah, that's what meant with the inner joins, and it is also my hope 😅

@sauloperez
Copy link
Contributor Author

sauloperez commented Mar 5, 2020

This apparently harmless change

     def order_permissions
-      return @order_permissions unless @order_permissions.nil?
-      @order_permissions = ::Permissions::Order.new(@user)
+      @order_permissions ||= ::Permissions::Order.new(@user)
     end

broke spec/features/consumer/shopping/embedded_groups_spec.rb:14 (broken build). It seems totally unrelated but... you know, embedded things... I removed the commit and this is ready for a 2nd approval.

@luisramos0
Copy link
Contributor

have you tried rerunning the build, embedded has a flaky spec.

@sauloperez
Copy link
Contributor Author

sauloperez commented Mar 5, 2020

have you tried rerunning the build, embedded has a flaky spec.

yes, like 3 times and it still failed. But I've seen that same spec failing in a build from one of your branches so it might as well be just an exceptionally flaky spec 🤷‍♂️ I just don't want to delay this PR any further.

@sauloperez
Copy link
Contributor Author

sauloperez commented Mar 10, 2020

This would benefit from a second approval but while we wait the problem is still there. So given the reduced scope of this change, I assume there is little risk and move it to test ready.

@RachL
Copy link
Contributor

RachL commented Mar 10, 2020

@sigmundpetersen why did you changed it back?

@sigmundpetersen
Copy link
Contributor

Yeah sorry, there are 2 PRs connected to the issue and I don't think the other one is Test ready. Maybe we should disconnect this one and test it seperately? And let the other remain in Code Review.

@RachL
Copy link
Contributor

RachL commented Mar 10, 2020

ok, thanks :) done!

@RachL RachL self-assigned this Mar 10, 2020
@RachL RachL added the pr-staged-fr staging.coopcircuits.fr label Mar 10, 2020
@RachL
Copy link
Contributor

RachL commented Mar 10, 2020

This is looking good so far on staging.

I have checked with several cases the OC reports and the packing report.

I did the other with simple producer profile.

The results were fine.

@sauloperez I didn't test the performance part, because I guess this will be looked at in production, correct?

@RachL RachL removed the pr-staged-fr staging.coopcircuits.fr label Mar 10, 2020
@sauloperez
Copy link
Contributor Author

@sauloperez I didn't test the performance part, because I guess this will be looked at in production, correct?

Exactly. The affected SQL query is taking less than half the time in "lab" conditions so I'm hoping this is going to have a noticeable and positive impact. We'll see.

@sauloperez sauloperez merged commit 802ac64 into openfoodfoundation:master Mar 10, 2020
@sauloperez sauloperez deleted the inner-join-visible-orders branch March 10, 2020 21:54
Copy link
Member

@mkllnk mkllnk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just discovered that I had a comment on this pull request that didn't get submitted somehow. Anyway, I'm reverting it now following #4782.

@@ -10,7 +10,7 @@ def initialize(user)
# Find orders that the user can see
def visible_orders
Spree::Order.
with_line_items_variants_and_products_outer.
with_line_items_variants_and_products.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This means that empty orders won't show any more, right? I'm not sure about the use case but I think it was possible to see empty carts this way.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we missing test coverage for some cases there?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it was possible to see empty carts this way

LEFT JOINS would allow that but I think we somehow filter them in a later step

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants