MERGE 优化

可以通过以下几种方式提高 MERGE 性能:

MERGE 操作的投影

Vertica 查询优化器会自动选择最佳投影来实施合并操作。良好投影设计策略提供的投影可帮助查询优化器避免额外的排序和数据传输操作,并提高 MERGE 性能。

例如,以下 MERGE 语句片段分别在 tgt.asrc.b 列上联接源表和目标表 tgt src

=> MERGE INTO tgt USING src ON tgt.a = src.b ...

如果 tgtsrc 表的投影采用以下投影设计之一(其中输入通过投影 ORDER BY 子句进行预排序),则 Vertica 可以使用局部合并联接:

  • 复制的投影按以下列进行排序:

    • tgt 的列 a

    • src 的列 b

  • 分段投影在以下列以相同方式进行分段

    • tgt 的列 a

    • src 的列 b

    • 相应的分段列

优化 MERGE 查询计划

如果满足以下条件,Vertica 即准备了一个经过优化的查询计划:

  • MERGE 语句同时包含两个匹配子句 WHEN MATCHED THEN UPDATE SETWHEN 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) 中的所有列都包含在 UPDATEINSERT 子句中。

  • UPDATEINSERT 子句指定相同的源值:s.as.bs.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.as.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 语句符合优化条件,请重写该语句,以使 UPDATEINSERT 子句中的源值相同:


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);