提交 f8664648 authored 作者: Thomas Mueller's avatar Thomas Mueller

Sorted insert optimization

上级 cad2f4bf
...@@ -723,9 +723,7 @@ public class Parser { ...@@ -723,9 +723,7 @@ public class Parser {
} }
} while (readIf(",")); } while (readIf(","));
read(")"); read(")");
IndexColumn[] cols = new IndexColumn[columns.size()]; return columns.toArray(new IndexColumn[columns.size()]);
columns.toArray(cols);
return cols;
} }
private String[] parseColumnList() throws SQLException { private String[] parseColumnList() throws SQLException {
...@@ -734,9 +732,7 @@ public class Parser { ...@@ -734,9 +732,7 @@ public class Parser {
String columnName = readColumnIdentifier(); String columnName = readColumnIdentifier();
columns.add(columnName); columns.add(columnName);
} while (readIfMore()); } while (readIfMore());
String[] cols = new String[columns.size()]; return columns.toArray(new String[columns.size()]);
columns.toArray(cols);
return cols;
} }
private Column[] parseColumnList(Table table) throws SQLException { private Column[] parseColumnList(Table table) throws SQLException {
...@@ -751,9 +747,7 @@ public class Parser { ...@@ -751,9 +747,7 @@ public class Parser {
columns.add(column); columns.add(column);
} while (readIfMore()); } while (readIfMore());
} }
Column[] cols = new Column[columns.size()]; return columns.toArray(new Column[columns.size()]);
columns.toArray(cols);
return cols;
} }
private boolean readIfMore() throws SQLException { private boolean readIfMore() throws SQLException {
...@@ -872,9 +866,7 @@ public class Parser { ...@@ -872,9 +866,7 @@ public class Parser {
} }
} while (readIfMore()); } while (readIfMore());
} }
Expression[] expr = new Expression[values.size()]; command.addRow(values.toArray(new Expression[values.size()]));
values.toArray(expr);
command.addRow(expr);
} while (readIf(",")); } while (readIf(","));
} else { } else {
command.setQuery(parseSelect()); command.setQuery(parseSelect());
...@@ -888,6 +880,9 @@ public class Parser { ...@@ -888,6 +880,9 @@ public class Parser {
read("INTO"); read("INTO");
Table table = readTableOrView(); Table table = readTableOrView();
command.setTable(table); command.setTable(table);
if (readIf("SORTED")) {
command.setSortedInsertMode(true);
}
if (readIf("(")) { if (readIf("(")) {
if (isToken("SELECT") || isToken("FROM")) { if (isToken("SELECT") || isToken("FROM")) {
command.setQuery(parseSelect()); command.setQuery(parseSelect());
...@@ -914,9 +909,7 @@ public class Parser { ...@@ -914,9 +909,7 @@ public class Parser {
} }
} while (readIfMore()); } while (readIfMore());
} }
Expression[] expr = new Expression[values.size()]; command.addRow(values.toArray(new Expression[values.size()]));
values.toArray(expr);
command.addRow(expr);
} while (readIf(",")); } while (readIf(","));
} else { } else {
command.setQuery(parseSelect()); command.setQuery(parseSelect());
...@@ -4635,6 +4628,9 @@ public class Parser { ...@@ -4635,6 +4628,9 @@ public class Parser {
command.setTableName(tableName); command.setTableName(tableName);
command.setComment(readCommentIf()); command.setComment(readCommentIf());
if (readIf("AS")) { if (readIf("AS")) {
if (readIf("SORTED")) {
command.setSortedInsertMode(true);
}
command.setQuery(parseSelect()); command.setQuery(parseSelect());
} else { } else {
read("("); read("(");
...@@ -4710,6 +4706,9 @@ public class Parser { ...@@ -4710,6 +4706,9 @@ public class Parser {
} while (readIfMore()); } while (readIfMore());
} }
if (readIf("AS")) { if (readIf("AS")) {
if (readIf("SORTED")) {
command.setSortedInsertMode(true);
}
command.setQuery(parseSelect()); command.setQuery(parseSelect());
} }
} }
......
...@@ -38,6 +38,7 @@ public class CreateTable extends SchemaCommand { ...@@ -38,6 +38,7 @@ public class CreateTable extends SchemaCommand {
private boolean onCommitTruncate; private boolean onCommitTruncate;
private Query asQuery; private Query asQuery;
private String comment; private String comment;
private boolean sortedInsertMode;
public CreateTable(Session session, Schema schema) { public CreateTable(Session session, Schema schema) {
super(session, schema); super(session, schema);
...@@ -166,6 +167,7 @@ public class CreateTable extends SchemaCommand { ...@@ -166,6 +167,7 @@ public class CreateTable extends SchemaCommand {
session.setUndoLogEnabled(false); session.setUndoLogEnabled(false);
Insert insert = null; Insert insert = null;
insert = new Insert(session); insert = new Insert(session);
insert.setSortedInsertMode(sortedInsertMode);
insert.setQuery(asQuery); insert.setQuery(asQuery);
insert.setTable(table); insert.setTable(table);
insert.prepare(); insert.prepare();
...@@ -258,4 +260,8 @@ public class CreateTable extends SchemaCommand { ...@@ -258,4 +260,8 @@ public class CreateTable extends SchemaCommand {
data.persistData = persistData; data.persistData = persistData;
} }
public void setSortedInsertMode(boolean sortedInsertMode) {
this.sortedInsertMode = sortedInsertMode;
}
} }
...@@ -11,10 +11,12 @@ import java.sql.SQLException; ...@@ -11,10 +11,12 @@ import java.sql.SQLException;
import org.h2.command.Command; import org.h2.command.Command;
import org.h2.command.Prepared; import org.h2.command.Prepared;
import org.h2.constant.ErrorCode; import org.h2.constant.ErrorCode;
import org.h2.engine.Database;
import org.h2.engine.Right; import org.h2.engine.Right;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.expression.Expression; import org.h2.expression.Expression;
import org.h2.expression.Parameter; import org.h2.expression.Parameter;
import org.h2.index.PageIndex;
import org.h2.log.UndoLogRecord; import org.h2.log.UndoLogRecord;
import org.h2.message.Message; import org.h2.message.Message;
import org.h2.result.LocalResult; import org.h2.result.LocalResult;
...@@ -35,6 +37,7 @@ public class Insert extends Prepared { ...@@ -35,6 +37,7 @@ public class Insert extends Prepared {
private Column[] columns; private Column[] columns;
private ObjectArray<Expression[]> list = ObjectArray.newInstance(); private ObjectArray<Expression[]> list = ObjectArray.newInstance();
private Query query; private Query query;
private boolean sortedInsertMode;
public Insert(Session session) { public Insert(Session session) {
super(session); super(session);
...@@ -69,6 +72,22 @@ public class Insert extends Prepared { ...@@ -69,6 +72,22 @@ public class Insert extends Prepared {
} }
public int update() throws SQLException { public int update() throws SQLException {
Database db = session.getDatabase();
PageIndex index = null;
if (sortedInsertMode && db.isPageStoreEnabled() && db.isPersistent()) {
index = (PageIndex) table.getScanIndex(session);
index.setSortedInsertMode(true);
}
try {
return insertRows();
} finally {
if (index != null) {
index.setSortedInsertMode(false);
}
}
}
private int insertRows() throws SQLException {
int count; int count;
session.getUser().checkRight(table, Right.INSERT); session.getUser().checkRight(table, Right.INSERT);
setCurrentRowNumber(0); setCurrentRowNumber(0);
...@@ -210,4 +229,8 @@ public class Insert extends Prepared { ...@@ -210,4 +229,8 @@ public class Insert extends Prepared {
return null; return null;
} }
public void setSortedInsertMode(boolean sortedInsertMode) {
this.sortedInsertMode = sortedInsertMode;
}
} }
...@@ -398,8 +398,7 @@ public class Select extends Query { ...@@ -398,8 +398,7 @@ public class Select extends Query {
} }
sortColumns.add(exprCol.getColumn()); sortColumns.add(exprCol.getColumn());
} }
Column[] sortCols = new Column[sortColumns.size()]; Column[] sortCols = sortColumns.toArray(new Column[sortColumns.size()]);
sortColumns.toArray(sortCols);
int[] sortTypes = sort.getSortTypes(); int[] sortTypes = sort.getSortTypes();
if (sortCols.length == 0) { if (sortCols.length == 0) {
// sort just on constants - can use scan index // sort just on constants - can use scan index
...@@ -792,8 +791,7 @@ public class Select extends Query { ...@@ -792,8 +791,7 @@ public class Select extends Query {
} }
private double preparePlan() throws SQLException { private double preparePlan() throws SQLException {
TableFilter[] topArray = new TableFilter[topFilters.size()]; TableFilter[] topArray = topFilters.toArray(new TableFilter[topFilters.size()]);
topFilters.toArray(topArray);
for (TableFilter t : topArray) { for (TableFilter t : topArray) {
t.setFullCondition(condition); t.setFullCondition(condition);
} }
...@@ -846,8 +844,7 @@ public class Select extends Query { ...@@ -846,8 +844,7 @@ public class Select extends Query {
// can not use the field sqlStatement because the parameter // can not use the field sqlStatement because the parameter
// indexes may be incorrect: ? may be in fact ?2 for a subquery // indexes may be incorrect: ? may be in fact ?2 for a subquery
// but indexes may be set manually as well // but indexes may be set manually as well
Expression[] exprList = new Expression[expressions.size()]; Expression[] exprList = expressions.toArray(new Expression[expressions.size()]);
expressions.toArray(exprList);
StatementBuilder buff = new StatementBuilder("SELECT "); StatementBuilder buff = new StatementBuilder("SELECT ");
if (distinct) { if (distinct) {
buff.append("DISTINCT "); buff.append("DISTINCT ");
......
...@@ -156,6 +156,9 @@ public class PageDataLeaf extends PageData { ...@@ -156,6 +156,9 @@ public class PageDataLeaf extends PageData {
// required, otherwise the index doesn't work correctly // required, otherwise the index doesn't work correctly
return entryCount / 2; return entryCount / 2;
} }
if (index.isSortedInsertMode()) {
return x < 2 ? 1 : x > entryCount - 1 ? entryCount - 1 : x;
}
// split near the insertion point to better fill pages // split near the insertion point to better fill pages
// split in half would be: // split in half would be:
// return entryCount / 2; // return entryCount / 2;
......
...@@ -18,6 +18,8 @@ public abstract class PageIndex extends BaseIndex { ...@@ -18,6 +18,8 @@ public abstract class PageIndex extends BaseIndex {
*/ */
protected int rootPageId; protected int rootPageId;
private boolean sortedInsertMode;
public int getRootPageId() { public int getRootPageId() {
return rootPageId; return rootPageId;
} }
...@@ -31,4 +33,12 @@ public abstract class PageIndex extends BaseIndex { ...@@ -31,4 +33,12 @@ public abstract class PageIndex extends BaseIndex {
*/ */
public abstract void writeRowCount() throws SQLException; public abstract void writeRowCount() throws SQLException;
public void setSortedInsertMode(boolean sortedInsertMode) {
this.sortedInsertMode = sortedInsertMode;
}
boolean isSortedInsertMode() {
return sortedInsertMode;
}
} }
...@@ -72,7 +72,7 @@ import org.h2.value.ValueString; ...@@ -72,7 +72,7 @@ import org.h2.value.ValueString;
* The format of page 1 and 2 is: * The format of page 1 and 2 is:
* <ul> * <ul>
* <li>CRC32 of the remaining data: int (0-3)</li> * <li>CRC32 of the remaining data: int (0-3)</li>
* <li>write counter (incremented each time something is written): long (4-11)</li> * <li>write counter (incremented on each write): long (4-11)</li>
* <li>log trunk key: int (12-15)</li> * <li>log trunk key: int (12-15)</li>
* <li>log trunk page (0 for none): int (16-19)</li> * <li>log trunk page (0 for none): int (16-19)</li>
* <li>log data page (0 for none): int (20-23)</li> * <li>log data page (0 for none): int (20-23)</li>
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论