带有 CASE 语句的 PostgreSQL 慢连接
PostgreSQL slow JOIN with CASE statement
在我的数据库中,我有一个 table,其中包含约 3500 条记录,作为更复杂查询的一部分,我尝试使用 "CASE" 条件对自身执行内部联接,就像您可以的那样见下文。
SELECT *
FROM some_table AS t1
JOIN some_table AS t2 ON t1.type = t2.type
AND CASE
WHEN t1.type = 'ab' THEN t1.first = t2.first
WHEN t1.type = 'cd' THEN t1.second = t2.second
-- Column type contains only one of 2 possible varchar values
END;
问题是这个查询执行了 3.2 - 4.5 秒,而下一个请求执行了 40 - 50 毫秒。
SELECT *
FROM some_table AS t1
JOIN some_table AS t2 ON t1.type = t2.type
AND (t1.first = t2.first OR t1.second = t2.second)
同样根据第一种情况的执行计划,数据库处理了约 580 万条记录,而 table 仅包含约 3500 条记录。 table 上还有下一个索引:(id), (type), (type, first), (type, second)。
我们正在使用下一个版本:
x86_64-unknown-linux-gnu 上的 PostgreSQL 9.4.5,由 gcc (GCC) 4.4.7 20120 编译
313(红帽 4.4.7-16),64 位
知道为什么 PostgreSQL 在这种情况下工作如此奇怪吗?
测试这个:
select *
from
some_table as t1
join
some_table as t2 on
t1.type = t2.type
and
(
t1.type = 'ab' and t1.first = t2.first
or
t1.type = 'cd' and t1.second = t2.second
)
为了更好的性能,创建一个基于函数的索引:
create or replace function f (_type text, _first int, _second int)
returns integer as $$
select case _type when 'ab' then _first else _second end;
$$ language sql immutable;
create index i on some_table(f(type, first, second));
在查询中使用该索引:
select *
from
some_table as t1
join
some_table as t2 on
t1.type = t2.type
and
f(t1.type, t1.first, t1.second) = f(t1.type, t2.first, t2.second)
在我的数据库中,我有一个 table,其中包含约 3500 条记录,作为更复杂查询的一部分,我尝试使用 "CASE" 条件对自身执行内部联接,就像您可以的那样见下文。
SELECT *
FROM some_table AS t1
JOIN some_table AS t2 ON t1.type = t2.type
AND CASE
WHEN t1.type = 'ab' THEN t1.first = t2.first
WHEN t1.type = 'cd' THEN t1.second = t2.second
-- Column type contains only one of 2 possible varchar values
END;
问题是这个查询执行了 3.2 - 4.5 秒,而下一个请求执行了 40 - 50 毫秒。
SELECT *
FROM some_table AS t1
JOIN some_table AS t2 ON t1.type = t2.type
AND (t1.first = t2.first OR t1.second = t2.second)
同样根据第一种情况的执行计划,数据库处理了约 580 万条记录,而 table 仅包含约 3500 条记录。 table 上还有下一个索引:(id), (type), (type, first), (type, second)。
我们正在使用下一个版本: x86_64-unknown-linux-gnu 上的 PostgreSQL 9.4.5,由 gcc (GCC) 4.4.7 20120 编译 313(红帽 4.4.7-16),64 位
知道为什么 PostgreSQL 在这种情况下工作如此奇怪吗?
测试这个:
select *
from
some_table as t1
join
some_table as t2 on
t1.type = t2.type
and
(
t1.type = 'ab' and t1.first = t2.first
or
t1.type = 'cd' and t1.second = t2.second
)
为了更好的性能,创建一个基于函数的索引:
create or replace function f (_type text, _first int, _second int)
returns integer as $$
select case _type when 'ab' then _first else _second end;
$$ language sql immutable;
create index i on some_table(f(type, first, second));
在查询中使用该索引:
select *
from
some_table as t1
join
some_table as t2 on
t1.type = t2.type
and
f(t1.type, t1.first, t1.second) = f(t1.type, t2.first, t2.second)