MERGE 优化
可以通过以下几种方式提高 MERGE
性能:
-
使用小于目标表的源表。
MERGE 操作的投影
Vertica 查询优化器会自动选择最佳投影来实施合并操作。良好投影设计策略提供的投影可帮助查询优化器避免额外的排序和数据传输操作,并提高 MERGE
性能。
例如,以下 MERGE
语句片段分别在 tgt.a
和 src.b
列上联接源表和目标表 tgt
和 src
:
=> MERGE INTO tgt USING src ON tgt.a = src.b ...
如果 tgt
和 src
表的投影采用以下投影设计之一(其中输入通过投影 ORDER BY
子句进行预排序),则 Vertica 可以使用局部合并联接:
优化 MERGE 查询计划
如果满足以下条件,Vertica 即准备了一个经过优化的查询计划:
-
MERGE
语句同时包含两个匹配子句WHEN MATCHED THEN UPDATE SET
和WHEN NOT MATCHED THEN INSERT
。如果MERGE
语句仅包含一个匹配子句,那么它使用的是未经优化的查询计划。 -
MERGE
语句不包括更新和插入筛选器。 -
目标表联接列具有唯一键或主键约束。此要求不适用于源表联接列。
-
两个匹配子句指定目标表中的所有列。
-
两个匹配子句指定相同的源值。
有关评估
EXPLAIN
生成的查询计划的详细信息,请参阅 MERGE 路径。
后面的示例使用一个简单的架构来说明 Vertica 在哪些条件下会为 MERGE
准备优化查询计划,在哪些条件下不会准备该计划:
CREATE TABLE target(a INT PRIMARY KEY, b INT, c INT) ORDER BY b,a;
CREATE TABLE source(a INT, b INT, c INT) ORDER BY b,a;
INSERT INTO target VALUES(1,2,3);
INSERT INTO target VALUES(2,4,7);
INSERT INTO source VALUES(3,4,5);
INSERT INTO source VALUES(4,6,9);
COMMIT;
经过优化的 MERGE 语句
Vertica 可以为以下 MERGE
语句准备一个经过优化的查询计划,原因是:
-
目标表的联接列
t.a
具有主键约束。 -
目标表
(a,b,c)
中的所有列都包含在UPDATE
和INSERT
子句中。 -
UPDATE
和INSERT
子句指定相同的源值:s.a
、s.b
和s.c
。
MERGE INTO target t USING source s ON t.a = s.a
WHEN MATCHED THEN UPDATE SET a=s.a, b=s.b, c=s.c
WHEN NOT MATCHED THEN INSERT(a,b,c) VALUES(s.a, s.b, s.c);
OUTPUT
--------
2
(1 row)
输出值 2 表示成功,同时也说明了源中更新/插入到目标的行数。
未优化 MERGE 语句
在下一个示例中,MERGE
语句在未经优化的情况下运行,因为 UPDATE/INSERT
子句中的源值不相同。具体来说,UPDATE
子句包括列 s.a
和 s.c
的常数,而 INSERT
子句不包括:
MERGE INTO target t USING source s ON t.a = s.a
WHEN MATCHED THEN UPDATE SET a=s.a + 1, b=s.b, c=s.c - 1
WHEN NOT MATCHED THEN INSERT(a,b,c) VALUES(s.a, s.b, s.c);
为了使前面的 MERGE
语句符合优化条件,请重写该语句,以使 UPDATE
和 INSERT
子句中的源值相同:
MERGE INTO target t USING source s ON t.a = s.a
WHEN MATCHED THEN UPDATE SET a=s.a + 1, b=s.b, c=s.c -1
WHEN NOT MATCHED THEN INSERT(a,b,c) VALUES(s.a + 1, s.b, s.c - 1);