使用from子句子查询中的union提高查询性能

时间:2014-02-20 22:32:36

标签: sql postgresql subquery union

如何改善此查询的效果?我有一个关于c1的索引,并且在tb1上没有选择主键。我的目标是为每个c3实例创建一条记录。

select 
t1.*

into tb2

from (
select 
c1,
c2,
c3
from tb1
where c1 = '1'

union

select 
c1,
c2,
c4
from tb1
where c1 = '1'
) as t1
where t1.c3 != ''

表定义(PG v9.0):

CREATE TABLE tb1 (
  c1 text
  c2 text
  c3 text
  c4 text
);

指数:

CREATE INDEX c1_idx   ON tb1 USING btree (c1);

1 个答案:

答案 0 :(得分:0)

CREATE TABLE tb2 AS 
SELECT c1, c2, c3
FROM   tb1
WHERE  c1 = '1'
AND    c3 <> ''

UNION ALL
SELECT c1, c2, c4
FROM   tb1
WHERE  c1 = '1'
AND    c4 <> '';
  • 除非您想要消除可能的重复项,否则请使用UNION ALL。快点。如果出现重复,结果会有所不同!
  • 不需要子查询。
  • 使用CREATE TABLE AS代替SELECT INTOPer documentation
  

此命令在功能上与SELECT INTO类似,但确实如此   因为它不太可能与其他用途混淆   SELECT INTO语法。此外,CREATE TABLE AS提供了一个超集   SELECT INTO提供的功能。

  • '1'周围的单引号表示您将数字数据存储为字符串类型。如果是这样,那就不好了。考虑appropriate data types ...

替代CTE

如果表格很大,那么CTE的替代方案可能会更快,因为我们只读了一次。

还包括来自评论的其他请求,添加列,添加pk:

CREATE TABLE tb2 AS 
WITH cte AS (
   SELECT c1, c2, c3, c4
   FROM   tb1
   WHERE  c1 = '1'
   AND   (c3 <> '' OR c4 <> '')
   )
SELECT c1, c2, c3, NULL::text AS new_column  -- add new column
FROM   cte
WHERE  c3 <> ''

UNION ALL
SELECT c1, c2, c4, NULL
FROM   cte
WHERE  c4 <> '';

-- add primary key:
ALTER TABLE tb2 ADD CONSTRAINT tb2_pkey PRIMARY KEY(???);

如果表格很大,您可能希望增加temp_buffers设置(仅适用于会话)。有关答案的更多信息:
How to delete duplicate entries?

如果你需要经常运行(并且不介意写操作的小惩罚),并且如果你可以定义行的超集来消除其余的大部分,我会建议partial index ...