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

The MERGE statement is now about 30% faster when using a PreparedStatement.

上级 dcbd0115
...@@ -18,7 +18,8 @@ Change Log ...@@ -18,7 +18,8 @@ Change Log
<h1>Change Log</h1> <h1>Change Log</h1>
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul><li>Multi-column indexes where the second or later column was descending did not always <ul><li>The MERGE statement is now about 30% faster when using a PreparedStatement.
</li><li>Multi-column indexes where the second or later column was descending did not always
produce correct results (rows were missing in the result set, or the result set was empty). produce correct results (rows were missing in the result set, or the result set was empty).
</li><li>When using large transactions or a small log size, the database could get very slow </li><li>When using large transactions or a small log size, the database could get very slow
(profiling shows the hotspot is in FileObjectDisk.sync()). (profiling shows the hotspot is in FileObjectDisk.sync()).
......
...@@ -80,27 +80,6 @@ public class Merge extends Prepared { ...@@ -80,27 +80,6 @@ public class Merge extends Prepared {
int count; int count;
session.getUser().checkRight(table, Right.INSERT); session.getUser().checkRight(table, Right.INSERT);
session.getUser().checkRight(table, Right.UPDATE); session.getUser().checkRight(table, Right.UPDATE);
if (keys == null) {
Index idx = table.getPrimaryKey();
if (idx == null) {
throw DbException.get(ErrorCode.CONSTRAINT_NOT_FOUND_1, "PRIMARY KEY");
}
keys = idx.getColumns();
}
StatementBuilder buff = new StatementBuilder("UPDATE ");
buff.append(table.getSQL()).append(" SET ");
for (Column c : columns) {
buff.appendExceptFirst(", ");
buff.append(c.getSQL()).append("=?");
}
buff.append(" WHERE ");
buff.resetCount();
for (Column c : keys) {
buff.appendExceptFirst(" AND ");
buff.append(c.getSQL()).append("=?");
}
String sql = buff.toString();
update = session.prepare(sql);
setCurrentRowNumber(0); setCurrentRowNumber(0);
session.setLastIdentity(ValueLong.get(0)); session.setLastIdentity(ValueLong.get(0));
if (list.size() > 0) { if (list.size() > 0) {
...@@ -263,6 +242,27 @@ public class Merge extends Prepared { ...@@ -263,6 +242,27 @@ public class Merge extends Prepared {
throw DbException.get(ErrorCode.COLUMN_COUNT_DOES_NOT_MATCH); throw DbException.get(ErrorCode.COLUMN_COUNT_DOES_NOT_MATCH);
} }
} }
if (keys == null) {
Index idx = table.getPrimaryKey();
if (idx == null) {
throw DbException.get(ErrorCode.CONSTRAINT_NOT_FOUND_1, "PRIMARY KEY");
}
keys = idx.getColumns();
}
StatementBuilder buff = new StatementBuilder("UPDATE ");
buff.append(table.getSQL()).append(" SET ");
for (Column c : columns) {
buff.appendExceptFirst(", ");
buff.append(c.getSQL()).append("=?");
}
buff.append(" WHERE ");
buff.resetCount();
for (Column c : keys) {
buff.appendExceptFirst(" AND ");
buff.append(c.getSQL()).append("=?");
}
String sql = buff.toString();
update = session.prepare(sql);
} }
public boolean isTransactional() { public boolean isTransactional() {
......
...@@ -4322,8 +4322,8 @@ EXPLAIN SELECT * FROM TEST WHERE ID=1; ...@@ -4322,8 +4322,8 @@ EXPLAIN SELECT * FROM TEST WHERE ID=1;
EXPLAIN MERGE INTO TEST VALUES(1, 'Hello'); EXPLAIN MERGE INTO TEST VALUES(1, 'Hello');
> PLAN > PLAN
> ---------------------------------------------------- > ------------------------------------------------------------
> MERGE INTO PUBLIC.TEST(ID, NAME) VALUES (1, 'Hello') > MERGE INTO PUBLIC.TEST(ID, NAME) KEY(ID) VALUES (1, 'Hello')
> rows: 1 > rows: 1
MERGE INTO TEST VALUES(1, 'Hello'); MERGE INTO TEST VALUES(1, 'Hello');
...@@ -4343,8 +4343,8 @@ MERGE INTO TEST(ID, NAME) VALUES(3, 'How are you'); ...@@ -4343,8 +4343,8 @@ MERGE INTO TEST(ID, NAME) VALUES(3, 'How are you');
EXPLAIN MERGE INTO TEST(ID, NAME) VALUES(3, 'How are you'); EXPLAIN MERGE INTO TEST(ID, NAME) VALUES(3, 'How are you');
> PLAN > PLAN
> ---------------------------------------------------------- > ------------------------------------------------------------------
> MERGE INTO PUBLIC.TEST(ID, NAME) VALUES (3, 'How are you') > MERGE INTO PUBLIC.TEST(ID, NAME) KEY(ID) VALUES (3, 'How are you')
> rows: 1 > rows: 1
MERGE INTO TEST(ID, NAME) KEY(ID) VALUES(3, 'How do you do'); MERGE INTO TEST(ID, NAME) KEY(ID) VALUES(3, 'How do you do');
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论