提交 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
<h1>Change Log</h1>
<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).
</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()).
......
......@@ -80,27 +80,6 @@ public class Merge extends Prepared {
int count;
session.getUser().checkRight(table, Right.INSERT);
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);
session.setLastIdentity(ValueLong.get(0));
if (list.size() > 0) {
......@@ -263,6 +242,27 @@ public class Merge extends Prepared {
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() {
......
......@@ -4322,8 +4322,8 @@ EXPLAIN SELECT * FROM TEST WHERE ID=1;
EXPLAIN MERGE INTO TEST VALUES(1, 'Hello');
> PLAN
> ----------------------------------------------------
> MERGE INTO PUBLIC.TEST(ID, NAME) VALUES (1, 'Hello')
> ------------------------------------------------------------
> MERGE INTO PUBLIC.TEST(ID, NAME) KEY(ID) VALUES (1, 'Hello')
> rows: 1
MERGE INTO TEST VALUES(1, 'Hello');
......@@ -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');
> 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
MERGE INTO TEST(ID, NAME) KEY(ID) VALUES(3, 'How do you do');
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论