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

Fix compile time verification performance regression for sqlite #1946

Merged

Conversation

liningpan
Copy link
Contributor

@liningpan liningpan commented Jul 2, 2022

The sqlite CTE feature (#1816) introduced severe performance degradation, and this PR attempts to fix it.

This patch drastically reduces search space by adding memorization based on register type and cursor data type. Pushing new states on to the Stack is guarded by a HashSet, where if no new information is gained about an instruction (i.e. different register/cursor data type), the instruction will not be searched again.

Now the example query in #1921 only takes 5s to verify instead of several minutes. It might be possible to further optimize this by stop tracking unnecessary information, which could save a lot of memory allocations.

@abonander
Copy link
Collaborator

Do you mind looking at the failing CI checks?

@liningpan liningpan force-pushed the fix-sqlite-explain-performance branch from 4a06161 to fbc796b Compare August 1, 2022 17:22
zehnm added a commit to unfoldedcircle/api-model-rs that referenced this pull request Aug 7, 2022
Update to 0.6.1 isn't possible right now due to massive increase in
compile time and memory usage. The core build uses 30GB after a few
minutes! With 0.5.13 the build takes less than a minute and < 2GB.

See launchbadge/sqlx#1921
Possible fix with launchbadge/sqlx#1946
@abonander
Copy link
Collaborator

@liningpan do you have time to address the CI failures I mentioned before? The logs are gone now but if you amend your commit to update the SHA and push it to re-run the workflows we'll get new logs.

@liningpan
Copy link
Contributor Author

liningpan commented Sep 3, 2022 via email

@abonander
Copy link
Collaborator

abonander commented Sep 3, 2022

Yeah, sorry. It's easy to get sidetracked and forget about PRs in the queue. I don't even have the "Approve and Run" button anymore though, you'll need to update the branch for it to come back I think. A simple rebase should do it.

@liningpan liningpan force-pushed the fix-sqlite-explain-performance branch from fbc796b to 92289c0 Compare September 3, 2022 02:13
@liningpan
Copy link
Contributor Author

Although the CI pipeline appears to be passing, I'm not 100% certain about the correctness of this patch and the additional memory consumed by the branch state hash table. That being said it should still use way less memory than what's previously stored in the query history structure.

I would also like to hear the original author's (sqlite CTE #1816) opinion @tyrelr.

@tyrelr
Copy link
Contributor

tyrelr commented Sep 6, 2022

Overall, I think this is a good approach and it worked when I tested it. It is a bit unfortunate to need a 3rd way of storing column-states. But there is no simple way to avoid that due to HashMaps not implementing Hash (with good reason).

Based on reading the code, the only piece of information that seems to be discarded is which register is pointed at by a PseudoCursor. That should be almost impossible to cause an issue in practice. Literally everything in the state except that pseudocursor would need to be identical to cause a mistaken short-circuit. Then, for that mistaken short-circuit to matter, the two nearly identical states would need to result in significantly different output data types. Such a query plan would be valid, but would be unlike any other query plan I've seen sqlite generate.

@abonander
Copy link
Collaborator

@liningpan @tyrelr is it possible for this PR to cause type/null inference changes?

@tyrelr
Copy link
Contributor

tyrelr commented Sep 14, 2022

In practice, I expect that a different result would never actually happen. It requires a very atypical query plan for the issue above to occur, I expect sqlite would never generate such a plan.

But theoretically, this could change type/null inference if sqlite DID happen to generate that weird query plan.

@abonander abonander changed the base branch from main to 0.7-dev September 15, 2022 01:12
@abonander
Copy link
Collaborator

For safety, I've earmarked this for 0.7.0, which I've started working on.

@abonander abonander merged commit 1379eb6 into launchbadge:0.7-dev Sep 15, 2022
@cycraig cycraig mentioned this pull request Sep 18, 2022
abonander pushed a commit that referenced this pull request Feb 18, 2023
* add instruction, register, and cursor state memorization

* fix: fixed formating
abonander pushed a commit that referenced this pull request Feb 21, 2023
* add instruction, register, and cursor state memorization

* fix: fixed formating
Aandreba pushed a commit to Aandreba/sqlx that referenced this pull request Mar 31, 2023
…chbadge#1946)

* add instruction, register, and cursor state memorization

* fix: fixed formating
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

3 participants