Use ARRAY instead of IN queries for Better Perf in Flat PG Collections#258
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #258 +/- ##
============================================
- Coverage 80.48% 80.41% -0.07%
- Complexity 1330 1337 +7
============================================
Files 231 231
Lines 6020 6060 +40
Branches 537 545 +8
============================================
+ Hits 4845 4873 +28
- Misses 808 813 +5
- Partials 367 374 +7
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
| /** | ||
| * Generates SQL for scalar IN operator (used when array field has been unnested). Example: | ||
| * "tags_unnested" IN (?, ?, ?) | ||
| * "tags_unnested" = ANY(ARRAY[?, ?, ?]) |
There was a problem hiding this comment.
@suddendust Why do we have multiple placeholders in ANY? This should be just one placeholder. If the placeholders are variable query plan will not be cached.
Also, even if we use IN, postgres query planner is automatically converting queries to ANY.
There was a problem hiding this comment.
You're right. I am actually testing this. Basically, using just one placeholder for the entire array.
| */ | ||
| public static String inferSqlTypeFromValue(Object[] values) { | ||
| if (values.length == 0) { | ||
| return "text"; |
There was a problem hiding this comment.
will this cause issues when type of the column is not text?
There was a problem hiding this comment.
Yes, there'd be an issue, found this in texting. Fixed this now.
| * @param values Array of values to infer type from | ||
| * @return PostgreSQL internal type name: "int4", "float8", "bool", or "text" | ||
| */ | ||
| public static String inferSqlTypeFromValue(Object[] values) { |
There was a problem hiding this comment.
not very happy about this. How big is the lift to pass type information from entity service?
There was a problem hiding this comment.
We now just need to start passing in the type info in IdentifierExpression. That'd entail changes in document-store and then the corresponding changes in entity-service.
…ace_in_with_any_for_perf
…to replace_in_with_any_for_perf
…to replace_in_with_any_for_perf
|
|
||
| String placeholders = | ||
| if (values.length == 0) { | ||
| return "1 = 0"; |
Optimize IN/NOT IN Queries with
= ANY(ARRAY[])Overview
Replaced
IN ()syntax with= ANY(ARRAY[])for better PostgreSQL query performance across flat and nested JSON collections.SQL Examples
Flat/Top-level Scalar Fields
Before:
After:
Array Fields (overlap operator)
Before:
After:
NOT IN (flat collections)
Before:
After:
JSONB Array Fields
Before:
After:
Testing
[x] Add integration tests.
[x] Tested in a live env.