Skip to content

Commit

Permalink
Merge pull request #4041 from katzyn/index
Browse files Browse the repository at this point in the history
Reverse and incremental index sorting optimizations
  • Loading branch information
katzyn committed Apr 16, 2024
2 parents 49104cf + 9713b54 commit 0f29221
Show file tree
Hide file tree
Showing 41 changed files with 575 additions and 226 deletions.
2 changes: 2 additions & 0 deletions h2/src/docsrc/html/changelog.html
Expand Up @@ -21,6 +21,8 @@ <h1>Change Log</h1>

<h2>Next Version (unreleased)</h2>
<ul>
<li>Issue #701: An available index is never used for ordering, when the requested order is DESC
</li>
<li>Issue #4036: NULLS NOT DISTINCT constraint changed after column dropped
</li>
<li>Issue #4033: Wrong array produced when using ARRAY_AGG() on UNNEST(ARRAY[CAST(? AS INT)]) expression
Expand Down
11 changes: 11 additions & 0 deletions h2/src/docsrc/html/performance.html
Expand Up @@ -732,6 +732,17 @@ <h3>Special Optimizations</h3>
</p><p>
For queries of the form <code>SELECT * FROM TEST ORDER BY ID</code>, the query plan includes the line
<code>/* index sorted */</code> to indicate there is no separate sorting required.
<code>/* index sorted: 2 of 3 columns */</code> indicates that only some columns are sorted with an index.
An additional sorting is still required, but queries with the FETCH (TOP, LIMIT) clause
may still stop their execution earlier.
An index on <code>(A ASC, B ASC)</code> columns can be used for <code>ORDER BY A</code>, <code>ORDER BY A DESC</code>,
<code>ORDER BY A, B</code> or <code>ORDER BY A DESC, B DESC</code>.
With <code>ORDER BY A, B DESC</code> this index can only be used for ordering on the column <code>A</code>.
If columns are nullable, order of nulls is also important. Index on <code>(A ASC NULLS FIRST)</code> cannot be used for
<code>ORDER BY A ASC NULLS LAST</code>, but can be used for <code>ORDER BY A ASC NULLS FIRST</code> or
<code>ORDER BY A DESC NULLS LAST</code>.
When neither <code>NULLS FIRST</code> nor <code>NULLS LAST</code> is specified, a default is used, this default
is controlled by <a href="commands.html#set_default_null_ordering"><code>DEFAULT_NULL_ORDERING</code></a> setting.
</p><p>
For queries of the form <code>SELECT * FROM TEST GROUP BY ID ORDER BY ID</code>, the query plan includes the line
<code>/* group sorted */</code> to indicate there is no separate sorting required.
Expand Down
9 changes: 6 additions & 3 deletions h2/src/main/org/h2/bnf/context/DbContextRule.java
Expand Up @@ -89,7 +89,8 @@ public boolean autoComplete(Sentence sentence) {
best = quotedName;
bestSchema = schema;
}
} else if (s.isEmpty() || StringUtils.startsWithIgnoringCase(name, query) || StringUtils.startsWithIgnoringCase(quotedName, query)) {
} else if (s.isEmpty() || StringUtils.startsWithIgnoringCase(name, query)
|| StringUtils.startsWithIgnoringCase(quotedName, query)) {
if (s.length() < name.length()) {
sentence.add(name, name.substring(s.length()), type);
sentence.add(schema.quotedName + ".",
Expand All @@ -116,12 +117,14 @@ public boolean autoComplete(Sentence sentence) {
String name = table.getName();
String quotedName = StringUtils.quoteIdentifier(name);

if (StringUtils.startsWithIgnoringCase(query, name) || StringUtils.startsWithIgnoringCase("\"" + query, quotedName)) {
if (StringUtils.startsWithIgnoringCase(query, name)
|| StringUtils.startsWithIgnoringCase("\"" + query, quotedName)) {
if (best == null || name.length() > best.length()) {
best = name;
bestTable = table;
}
} else if (s.isEmpty() || StringUtils.startsWithIgnoringCase(name, query) || StringUtils.startsWithIgnoringCase(quotedName, query)) {
} else if (s.isEmpty() || StringUtils.startsWithIgnoringCase(name, query)
|| StringUtils.startsWithIgnoringCase(quotedName, query)) {
if (s.length() < name.length()) {
sentence.add(table.getQuotedName(),
table.getQuotedName().substring(s.length()),
Expand Down
6 changes: 4 additions & 2 deletions h2/src/main/org/h2/command/CommandRemote.java
Expand Up @@ -286,7 +286,8 @@ public BatchResult executeBatchUpdate(ArrayList<Value[]> batchParameters, Object
}
if (readGeneratedKeys) {
int columnCount = transfer.readInt();
ResultRemote remoteGeneratedKeys = new ResultRemote(session, transfer, objectId, columnCount, Integer.MAX_VALUE);
ResultRemote remoteGeneratedKeys = new ResultRemote(session, transfer, objectId,
columnCount, Integer.MAX_VALUE);
generatedKeys.add(remoteGeneratedKeys);
remoteGeneratedKeys.close();
}
Expand All @@ -310,7 +311,8 @@ public BatchResult executeBatchUpdate(ArrayList<Value[]> batchParameters, Object
autoCommit = transfer.readBoolean();
if (readGeneratedKeys) {
int columnCount = transfer.readInt();
ResultRemote remoteGeneratedKeys = new ResultRemote(session, transfer, objectId, columnCount, Integer.MAX_VALUE);
ResultRemote remoteGeneratedKeys = new ResultRemote(session, transfer, objectId,
columnCount, Integer.MAX_VALUE);
generatedKeys.add(remoteGeneratedKeys);
remoteGeneratedKeys.close();
}
Expand Down
2 changes: 1 addition & 1 deletion h2/src/main/org/h2/command/ddl/Analyze.java
Expand Up @@ -187,7 +187,7 @@ public static void analyzeTable(SessionLocal session, Table table, int sample, b
if (columnCount == 0) {
return;
}
Cursor cursor = table.getScanIndex(session).find(session, null, null);
Cursor cursor = table.getScanIndex(session).find(session, null, null, false);
if (cursor.next()) {
SelectivityData[] array = new SelectivityData[columnCount];
for (int i = 0; i < columnCount; i++) {
Expand Down
2 changes: 1 addition & 1 deletion h2/src/main/org/h2/command/dml/ScriptCommand.java
Expand Up @@ -474,7 +474,7 @@ private static <T extends DbObject> T[] sorted(Collection<T> collection, Class<T
private int generateInsertValues(int count, Table table) throws IOException {
PlanItem plan = table.getBestPlanItem(session, null, null, -1, null, null);
Index index = plan.getIndex();
Cursor cursor = index.find(session, null, null);
Cursor cursor = index.find(session, null, null, false);
Column[] columns = table.getColumns();
boolean withGenerated = false, withGeneratedAlwaysAsIdentity = false;
for (Column c : columns) {
Expand Down

0 comments on commit 0f29221

Please sign in to comment.