SQL,PostgreSQL:从一个表查询多个单元格的最佳方法

时间:2019-01-20 21:23:29

标签: sql postgresql

是否有更好的方式编写这组查询,以便表仅被扫描一次?

SELECT column1 FROM table WHERE id = 1;
SELECT column2 FROM table WHERE id = 2;
SELECT column3 FROM table WHERE id = 3;

这种替代方法有点浪费,因为当我只需要3时,它可以获取9个单元格。

SELECT column1, column2, column3 FROM table WHERE id IN (1, 2, 3);

是否有一种更有效的方法可以通过对表进行1次扫描来精确提取我需要的3个单元格?

3 个答案:

答案 0 :(得分:1)

使用

扫描表格一次
with t as (
  select * from tablename where id in (1, 2, 3)
)

,然后使用单独的select语句或union,仅扫描3条提取的行:

select column1 col from t where id = 1
union all
select column2 col from t where id = 2
union all
select column3 col from t where id = 3

请参见demo
或排成一排:

select 
  (select column1 from t where id = 1) column1,
  (select column2 from t where id = 2) column2,
  (select column3 from t where id = 3) column3;

请参见demo

答案 1 :(得分:0)

该表未“扫描”。当您寻找已经知道ID的三行时,将从主键索引(使用二进制搜索)中快速获取ID。因此,表地址是从索引中获取的,而行是直接从表地址中读取的。 (如果您查找未编入索引的列,情况将有所不同。)

但是,结合三个查询有两个原因:

  1. 每次将查询发送到DBMS时,都必须对其进行解释并建立访问计划。因此,最好发送一个查询而不是三个查询。
  2. 假设ID 1和3的行在磁盘块x上,ID 2的行在磁盘块y上。如果您一次要求所有三行,DBMS可能会通过要求#1,#3,#2而不是#1,#2,#3来优化磁盘访问。

组合查询为:

SELECT column1 AS col FROM table WHERE id = 1
UNION ALL
SELECT column2 AS col FROM table WHERE id = 2
UNION ALL
SELECT column3 AS col FROM table WHERE id = 3;

答案 2 :(得分:0)

首先,这三个查询不一定会扫描表三次。如果您在id上有索引,那么这只是索引查找。

SELECT column1 FROM table WHERE id = 1;
SELECT column2 FROM table WHERE id = 2;
SELECT column3 FROM table WHERE id = 3;

如果您真的喜欢,可以将查询改写为:

select (case when id = 1 then column1
             when id = 2 then column2
             when id = 3 then column3
        end)
from t
where id in (1, 2, 3);

这假定三列具有兼容的类型。