Skip to content

Run one instead of n queries #2982

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

Merged
merged 6 commits into from
Sep 21, 2021
Merged

Conversation

schmidt-sebastian
Copy link
Contributor

@schmidt-sebastian schmidt-sebastian commented Sep 16, 2021

Instead of running the same query a bunch of times (e.g. for IN queries), this PR now runs a query with multiple OR clauses. This allows SQLite to dedupe results.

I think this should never hit a statement limit since our query complexity is quite limited.

@google-cla google-cla bot added the cla: yes Override cla label Sep 16, 2021
@google-oss-bot
Copy link
Contributor

google-oss-bot commented Sep 16, 2021

Coverage Report

Affected SDKs

  • firebase-firestore

    SDK overall coverage changed from 43.16% (90efb98) to 43.14% (b7c5b76f) by -0.03%.

    Filename Base (90efb98) Head (b7c5b76f) Diff
    Bound.java 50.00% 33.93% -16.07%
    FieldIndex.java 75.00% 70.00% -5.00%
    SQLiteIndexManager.java 95.74% 95.83% +0.09%
    Target.java 97.09% 96.51% -0.58%
    Util.java 49.35% 52.94% +3.59%

Test Logs

Notes

HTML coverage reports can be produced locally with ./gradlew <product>:checkCoverage.
Report files are located at <product-build-dir>/reports/jacoco/.

Head commit (b7c5b76f) is created by Prow via merging commits: 90efb98 58a179c.

@google-oss-bot
Copy link
Contributor

google-oss-bot commented Sep 16, 2021

Binary Size Report

Affected SDKs

  • firebase-firestore

    Type Base (90efb98) Head (b7c5b76f) Diff
    aar 1.20 MB 1.20 MB +595 B (+0.0%)
    apk (release) 3.24 MB 3.24 MB +20 B (+0.0%)

Test Logs

Notes

Head commit (b7c5b76f) is created by Prow via merging commits: 90efb98 58a179c.

@schmidt-sebastian
Copy link
Contributor Author

/test device-check-changed

@schmidt-sebastian
Copy link
Contributor Author

cc @thebrianchen

Copy link
Contributor

@wu-hui wu-hui left a comment

Choose a reason for hiding this comment

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

I want to see how you feel about an alternative: using SQL 'UNION' instead.

There are some advantages with UNION:

  1. It is less sql text manipulating, the old code can be modified to simply concat the sql with UNION.
  2. This would also be mentally close to IndexedDb and LevelDb.
  3. My playing with sqlite query plan suggests UNION might be more efficient..

It looks like SQLite is not doing all optimization with connected OR filters, it will simply do a filter on index_id.

The query plan for using OR

sqlite> select * from index_entries_test where (index_id=1 and index_value >= 'x' and index_value <'z') or (index_id = 1 and index_value > 'a' and index_value <'c');
QUERY PLAN
`--SEARCH TABLE index_entries_test USING COVERING INDEX sqlite_autoindex_index_entries_test_1 (index_id=?)

The query plan for using UNION:

sqlite> select * from index_entries_test where (index_id = 1 and index_value > 'a' and index_value <'c')
   ...> union
   ...> select * from index_entries_test where (index_id=1 and index_value >= 'x' and index_value <'z')
   ...> order by index_value
   ...> limit 10
   ...> ;
QUERY PLAN
`--MERGE (UNION)
   |--LEFT
   |  `--SEARCH TABLE index_entries_test USING COVERING INDEX sqlite_autoindex_index_entries_test_1 (index_id=? AND index_value>? AND index_value<?)
   `--RIGHT
      `--SEARCH TABLE index_entries_test USING COVERING INDEX sqlite_autoindex_index_entries_test_1 (index_id=? AND index_value>? AND index_value<?)

@Nullable Bound upperBound = target.getUpperBound(fieldIndex);

if (Logger.isDebugEnabled()) {
Logger.warn(
Logger.debug(
Copy link
Contributor

Choose a reason for hiding this comment

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

The if check above is not neccessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is meant to reduce computation complexity as it avoids stringifying the protos.

Copy link
Contributor

Choose a reason for hiding this comment

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

Got it.

@wu-hui wu-hui assigned schmidt-sebastian and unassigned wu-hui Sep 17, 2021
Copy link
Contributor Author

@schmidt-sebastian schmidt-sebastian left a comment

Choose a reason for hiding this comment

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

Thanks for the great suggestion. Updated to use UNION, which is also a bit simpler.

@Nullable Bound upperBound = target.getUpperBound(fieldIndex);

if (Logger.isDebugEnabled()) {
Logger.warn(
Logger.debug(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is meant to reduce computation complexity as it avoids stringifying the protos.

@Nullable Bound upperBound = target.getUpperBound(fieldIndex);

if (Logger.isDebugEnabled()) {
Logger.warn(
Logger.debug(
Copy link
Contributor

Choose a reason for hiding this comment

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

Got it.

@wu-hui wu-hui assigned schmidt-sebastian and unassigned wu-hui Sep 20, 2021
@schmidt-sebastian schmidt-sebastian merged commit 45dd9ff into master Sep 21, 2021
@schmidt-sebastian schmidt-sebastian deleted the mrschmidt/querybuilder branch September 21, 2021 17:00
@firebase firebase locked and limited conversation to collaborators Oct 22, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants