我试图修复用于计算数据的查询的性能。在其中一个查询中,DB2 LUW的优化器选择执行嵌套循环连接而不是散列连接。
有问题的查询(导致NLJOIN)
with
source1 as (select COALESCE(CAST("LOGICAL_KEY" AS CHARACTER VARYING(4000)), ']#[') as LOGICAL_KEY from "SAMPLE"."SOURCE1"),
source2 as (select COALESCE(CAST("LOGICAL_KEY" AS CHARACTER VARYING(4000)), ']#[') as LOGICAL_KEY from "SAMPLE"."SOURCE2")
select count(*) from (
SELECT
"a"."LOGICAL_KEY",
"b"."LOGICAL_KEY"
FROM
source1 "a",
source2 "b"
WHERE
"a"."LOGICAL_KEY" =
"b"."LOGICAL_KEY"
);
但是,当我首先创建子查询表时,优化器会执行散列连接。
优化查询(导致HSJOIN)
CREATE TABLE "SAMPLE"."TMP_SOURCE1" ("LOGICAL_KEY" VARCHAR(4000 BYTE));
CREATE TABLE "SAMPLE"."TMP_SOURCE2" ("LOGICAL_KEY" VARCHAR(4000 BYTE));
insert into "SAMPLE"."TMP_SOURCE1" select COALESCE(CAST("LOGICAL_KEY" AS CHARACTER VARYING(4000)), ']#[') LOGICAL_KEY from "SAMPLE"."SOURCE1";
insert into "SAMPLE"."TMP_SOURCE2" select COALESCE(CAST("LOGICAL_KEY" AS CHARACTER VARYING(4000)), ']#[') LOGICAL_KEY from "SAMPLE"."SOURCE2";
select count(*) from (
SELECT
"a"."LOGICAL_KEY",
"b"."LOGICAL_KEY"
FROM
(select * from "SAMPLE"."TMP_SOURCE1") "a",
(select * from "SAMPLE"."TMP_SOURCE2") "b"
WHERE
"a"."LOGICAL_KEY" =
"b"."LOGICAL_KEY"
);
为什么DB2为相同的数据选择不同的路径?有没有办法强制结构与子查询执行散列连接?由于特权限制,我无法创建表格。
答案 0 :(得分:0)
您的设置中的db2level是什么?如果它是DB2 v9或更早版本,那么优化器甚至不考虑HSJOIN的一个原因是有问题的查询包含表达式上的连接谓词。在这种情况下,优化配置文件不是一种选择。使用会话表是个好主意。
从DB2 v10开始,HSJOIN也适用于表达式连接。因此,优化器开始考虑它。但最终决定仍以成本为基础。估计更便宜的计划胜出。
参考文献:
答案 1 :(得分:0)
从根本上说,你不是在比较苹果和苹果。在您的第一个场景中,构建表a和b正在作为查询的一部分完成,并且优化器将此工作作为其“整个连接策略”的一部分。由于它必须在内存中构建表,因此NLjoin扫描它们不是太多额外的工作。在第二种情况下,优化器会考虑两个具有等价谓词的现有表之间的连接,并发现HSjoin是可行的方法。