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

feat: Add optimization feature for composite cursors #62

Merged
merged 5 commits into from
May 30, 2024

Conversation

tadeboro
Copy link
Contributor

Current implementation of pagination on composite cursors is rather inefficient on large tables even in the presence of index. Changes in this commit add an optimization option that causes paginator to emit a bit different WHERE condition that query engines have an easier time optimizing.

We kept changes backward-compatible. We need to opt-in to get the new feature enabled.

Current implementation of pagination on composite cursors is rather
inefficient on large tables even in the presence of index. Changes in
this commit add an optimization option that causes paginator to emit a
bit different WHERE condition that query optimizators have an easier
time optimizing.

We kept changes backward-compatible. We need to opt-in to get the new
feature enabled.
@coveralls
Copy link

coveralls commented May 23, 2024

Pull Request Test Coverage Report for Build 9281306496

Details

  • 46 of 46 (100.0%) changed or added relevant lines in 2 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage increased (+0.3%) to 96.897%

Totals Coverage Status
Change from base Build 8872589309: 0.3%
Covered Lines: 406
Relevant Lines: 419

💛 - Coveralls

Copy link
Owner

@pilagod pilagod left a comment

Choose a reason for hiding this comment

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

This PR is so great. I haven't used tuple comparison before and indeed learn a lot from the changes, only a few minor suggestions. Thank you so much for the improvement.

One question would like to consult with you is that, making this feature optional is due to not all database vendors supporting this optimization, or not offering a consistent behavior of it, or perhaps any other considerations?

README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
Keys: []string{"ID"},
Limit: 10,
Order: DESC,
TupleCmp: DISABLED,
Copy link
Owner

Choose a reason for hiding this comment

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

What about just using bool for this flag, and default to false?

Copy link
Owner

@pilagod pilagod May 23, 2024

Choose a reason for hiding this comment

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

And AllowTupleCmp could be a better name to me, which is also aligning with the internal state.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We cannot use boolean directly here. Because of the way the configuration code is structured right now, each option needs to have some value that indicates the "not set, please ignore" state. For strings, we (ab)use "" for this purpose, and for integers, 0 is treated as unset marker. But since booleans only have two valid values that both carry meaning for us, we cannot use them directly.

This is why I opted to implement a new flag type that gives us that additional state. Alternatives would be:

  1. Use pointer to a boolean, which will give us nil as an additional state, but will make usage awkward (&false is not something we can do in go, so we would either need a monstrosity like &[]bool{false}[0] or a helper function).
  2. Do not allow resetting the tuple comparison option and treat false as an unset state option.

It would be ideal if Go's stdlib would provide an optional type that we could use here, but we are not there yet. And while I could write an Option[T] wrapper and use it here, that would stick out like a sore thumb from the rest of the code.

That being said, I am open to suggestions on how to proceed here.

Copy link
Owner

Choose a reason for hiding this comment

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

I agree with that pointer is bothering to use. 😔 Although the second alternative is more favorable to me, current options are all implemented based on a shared config structure, which might accidentally override the state if we treat false as unset. For instance:

paginator.New(
    WithAllowTupleCmp(true),
    // AllowTupleCmp would be overridden to false in other option
    WithRules(...)
)

Unless with further refinement of config and option, Flag would be the best choice to this feature. We can go for Flag at this moment. 🙌

What about the naming? In my opinion naming the flag to AllowTupleCmp would be more consistent across the whole codebase. 🙂

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What about the naming?

Sorry, I forgot to comment on that and update the code. I am OK with rename.

Copy link
Owner

Choose a reason for hiding this comment

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

That's fine. After document refinement, this PR is ready to go 🚀

README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
Co-authored-by: Cyan Ho <pilagooood@gmail.com>
@pilagod pilagod merged commit b99ed2b into pilagod:master May 30, 2024
3 checks passed
@pilagod
Copy link
Owner

pilagod commented May 30, 2024

@tadeboro I just released v2.6.0 to include this feature. Thank you so much for the contribution. 💪

@tadeboro tadeboro deleted the optimize-cursor-queries branch May 30, 2024 06:56
@tadeboro
Copy link
Contributor Author

@pilagod Thank you for you patience and reviews of my half-baked commits!

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.

3 participants