-
Notifications
You must be signed in to change notification settings - Fork 152
Optimize live orders queries based on confirmed_valid_to column #4055
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
base: main
Are you sure you want to change the base?
Conversation
Ethflow orders might have different validity than what user has signed submitted, resulting in the need of additional table to store this information. The need for joins slows down our queries getting all live orders. The new column `confirmed_valid_to` allows to store all needed data in the same table, treating normal and ethflow orders uniformly.
Only the database interfacing confirmed_valid_to is preserved.
|
Reminder: Please update the DB Readme and comment whether migrations are reversible (include rollback scripts if applicable).
Caused by: |
456acb1 to
f5e3e44
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request optimizes order queries by using a new confirmed_valid_to column, which is a good performance improvement. However, I've found a few critical issues that need to be addressed. There's a bug in how confirmed_valid_to is populated for ethflow orders, which could lead to incorrect query results. Additionally, a refactoring of the solvable_orders query seems incomplete and will cause the query to fail at runtime. I've also included some suggestions for further query optimization and documentation improvements.
| buy_amount: u256_to_big_decimal(&order_data.buy_amount), | ||
| valid_to: order_data.valid_to as i64, | ||
| // Confirmed valid_to from the contract | ||
| confirmed_valid_to: order_placement.order.validTo as i64, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The confirmed_valid_to field is being set to order_placement.order.validTo, which is the on-chain validTo value. However, for ethflow orders, this should be the user-specified valid_to to align with the query optimizations in crates/database/src/orders.rs.
The new query logic relies on confirmed_valid_to to correctly filter expired orders, and for ethflow orders, the user-specified valid_to (from ethflow_orders table) is the one that matters. The backfill logic in the migration file also confirms this expectation.
This is a critical issue as it will lead to incorrect filtering of ethflow orders. You'll need to refactor to pass the user valid_to (when available for ethflow orders) to this function and use it to populate confirmed_valid_to.
| AND NOT EXISTS (SELECT 1 FROM onchain_placed_orders op WHERE op.uid = o.uid AND op.placement_error IS NOT NULL) | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removing the trades_agg CTE here and the corresponding LEFT JOIN in a later change breaks the solvable_orders query. The SELECT list of the query (lines 757-759 in the file) still references the ta alias from this join to get sum_buy, sum_sell, and sum_fee.
Since ta will no longer be defined, the query will fail at runtime. To fix this, you should update the SELECT list to use subqueries to calculate these sums, similar to how it's done in the WHERE clause, or use a LATERAL join to compute the aggregates.
| sell_amount: u256_to_big_decimal(&expected_order_data.sell_amount), | ||
| buy_amount: u256_to_big_decimal(&expected_order_data.buy_amount), | ||
| valid_to: expected_order_data.valid_to as i64, | ||
| confirmed_valid_to: expected_order_data.valid_to as i64, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test sets confirmed_valid_to to the same value as valid_to. While this is correct for non-ethflow orders, it doesn't cover the case for ethflow orders where the user-specified valid_to can be different from the on-chain validTo.
To prevent regressions related to the bug I mentioned about populating confirmed_valid_to, I recommend extending this test or adding a new one to specifically cover the ethflow order scenario where these two valid_to values differ.
| WITH live_orders AS MATERIALIZED ( | ||
| SELECT o.* | ||
| FROM orders o | ||
| LEFT JOIN ethflow_orders e ON e.uid = o.uid |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The LEFT JOIN ethflow_orders e ON e.uid = o.uid seems to be redundant now. The e alias is not used in the WHERE clause of the live_orders CTE anymore, and the necessary data from ethflow_orders is fetched later in a LATERAL join (lines 795-800). Removing this join would make the query slightly more efficient.
| WITH live_orders AS MATERIALIZED ( | ||
| SELECT o.* | ||
| FROM orders o | ||
| LEFT JOIN ethflow_orders e ON e.uid = o.uid |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
database/README.md
Outdated
| confirmed_valid_to | timestamptz | not null | timestamp at which order is no longer executable. TODO: Ethflow details | ||
|
|
||
| Indexes: | ||
| - PRIMARY KEY: btree(`uid`) | ||
| - PRIMARY KEY: btree(`owner`, `confirmed_valid_to`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation for the new column and index has a few inaccuracies:
- The type for
confirmed_valid_tois listed astimestamptz, but the migration file defines it asbigint. - The
orderstable cannot have twoPRIMARY KEYs. The new index should be documented as a regular index. - The new index is on
(owner, confirmed_valid_to), but the migration file creates it only on(confirmed_valid_to). The documentation should match the implementation.
Please update the documentation to reflect the actual schema changes.
| */ | ||
|
|
||
| --index on `confirmed_valid_to` for quickly discarding expired ethflow orders | ||
| CREATE INDEX orders_owner_live_limit ON orders USING btree (confirmed_valid_to); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For better query performance, consider creating a composite index on (owner, confirmed_valid_to). The user_orders_with_quote query filters by both owner and confirmed_valid_to. A composite index on both columns would be more efficient for this query than the current index on just confirmed_valid_to.
CREATE INDEX orders_owner_live_limit ON orders USING btree (owner, confirmed_valid_to)f5e3e44 to
e88223b
Compare
e88223b to
b16b5d1
Compare
Description
Second part of #4047 which introduced optimized queries based on the introduced confirmed_valid_to column
It is crucial for the database to be already migrated manually as described in previous PR before applying this one.
Changes
How to test
Tested on a test-db created by @MartinquaXD which contains a snapshot of prod data. The optimized queries run significantly faster due to changes in
orderstable and new indices.Related Issues
#4021