【问题标题】:Inner join performance内连接性能
【发布时间】:2014-04-19 20:16:22
【问题描述】:

我有一张表,里面有很多外键,我需要进行内部连接,以便进行搜索。其中可能有 10 个以上,这意味着我必须进行 10 个内部连接。与我要连接它们的庞大(数百万行)表相比,要连接的每个表可能只有几行。

我只需要知道连接是否是一种快速的方法(仅使用 Postgres)来执行此操作,或者是否有更聪明的方法我可以使用子查询或其他方式来执行此操作。

这里以一些虚构的数据为例:

create table a (
   a_id serial primary key,
   name character varying(32)
);
create table b (
   b_id serial primary key,
   name character varying(32)
);

--just 2 tables for simplicity, but i really need like 10 or more

create table big_table (
   big_id serial primary key,
   a_id int references a(a_id),
   b_id int references b(b_id)
);

--filter big_table based on the name column of a and b
--big_table only contains fks to a and b, so in this example im using
--left joins so i can compare by the name column
select big_id,a.name,b.name from big_table
  left join a using (a_id)
  left join b using (b_id)
  where (? is null or a.name=?) and (? is null or b.name=?);

【问题讨论】:

  • 查询的目的是什么?您在结果中需要哪些列? WHERE 子句背后的意图是什么? Postgres 版本?

标签: sql postgresql join database-design postgresql-performance


【解决方案1】:

基本上,连接是一种快速的方法。哪种方式可能最快取决于确切的要求。一些提示:

  • 您的WHERE 子句的用途尚不清楚。您似乎打算加入 所有 查找表并为每个查找表包含一个条件,而实际上您只需要其中的一些。那是低效的。而是使用 并且只在查询中包含您实际需要的内容。

  • 对于当前查询,由于主表中的所有 fk 列都可以是 NULL,因此您必须使用 LEFT JOIN 而不是 JOIN,否则您将排除行fk 列中有NULL 值。

  • 查找表中的name 列当然应该定义为NOT NULL。而且我不会使用非描述性的列名"name",这是一个无用的命名约定。 I also would use text instead of varchar(32).

【讨论】:

  • 感谢您的建议!生病编辑我的问题,但这里有一个解释:where 子句是根据一些 fk 引用进行过滤的。例如,我想根据表ab 的名称列过滤big_tablebig_table 虽然只有 fks,所以要过滤 name 列 id 需要以某种方式组合它们。你对左连接是正确的。这就是我从头顶写下来的结果。别担心,它们并没有真正命名为name。不过,您关于使用约束而不是 varchar 的建议很棒。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-14
  • 1970-01-01
  • 2018-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多