Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
需要帮助了解联接查询与带有子选择的查询的SQL解释吗_Sql_Postgresql_Join_Query Optimization_Subquery - Fatal编程技术网

需要帮助了解联接查询与带有子选择的查询的SQL解释吗

需要帮助了解联接查询与带有子选择的查询的SQL解释吗,sql,postgresql,join,query-optimization,subquery,Sql,Postgresql,Join,Query Optimization,Subquery,我在这里发布了以前的一个问题,询问什么更好,JOIN查询或使用subselect的查询。链接: 这是对那个问题的延伸。谁能给我解释一下为什么我会看到我在这里看到的东西 查询(子选择): SELECT article_seq, title, synopsis, body, lastmodified_date, (SELECT type_id FROM types WHERE kbarticles.type = type_seq), status, scope, images, archived,

我在这里发布了以前的一个问题,询问什么更好,
JOIN
查询或使用subselect的查询。链接:

这是对那个问题的延伸。谁能给我解释一下为什么我会看到我在这里看到的东西

查询(子选择):

SELECT article_seq, title, synopsis, body, lastmodified_date, (SELECT type_id FROM types WHERE kbarticles.type = type_seq), status, scope, images, archived, author, owner, (SELECT owner_description FROM owners WHERE kbarticles.owner = owner_seq),  (SELECT review_date FROM kbreview WHERE kbarticles.article_seq = article_seq) FROM kbarticles WHERE article_seq = $1
解释分析(子选择)

查询(
JOIN
s)

解释分析(
JOIN
s)

根据我在上一个问题中给出(并被接受)的答案,
JOIN
s应该会有更好的结果。然而,在我所有的测试中,我发现
JOIN
s的结果会差几毫秒。似乎
JOIN
s也充满了嵌套循环。我要加入的所有表都被编入索引


我正在做一些我应该做的不同的事情吗?是否缺少某些内容?

此表列是否已编制索引?r、 第(二)条

->KBR上的顺序扫描(成本=0.00..14.54行=1宽度=12) (实际时间=0.267..1.175行=1 循环=1)


这是花费时间最多的地方。

考虑到两个计划都在做相同的表格扫描,只是以不同的方式安排,我认为两者之间没有显著差异。下臂生成单行的“嵌套循环”与单行子选择几乎相同


连接更一般,因为使用标量子选择不会扩展到从任何辅助表中获取两列,例如。

这些查询在逻辑上是不同的

第一个:

SELECT  article_seq, title, synopsis, body, lastmodified_date,
        (
        SELECT  type_id
        FROM    types
        WHERE   kbarticles.type = type_seq
        ),
        status, scope, images, archived, author, owner,
        (
        SELECT  owner_description
        FROM    owners
        WHERE   kbarticles.owner = owner_seq
        ),
        (
        SELECT  review_date
        FROM    kbreview
        WHERE   kbarticles.article_seq = article_seq
        )
FROM    kbarticles
WHERE   article_seq = $1
第二条:

SELECT  k.article_seq, k.title, k.synopsis, k.body, k.lastmodified_date, t.type_id, k.status,
        k.scope, k.images, k.archived, k.author, k.owner, o.owner_description, r.review_date
FROM    kbarticles k
JOIN    types t
ON      k.type = t.type_seq
JOIN    owners o
ON      k.owner = o.owner_seq
JOIN    kbreview r
ON      k.article_seq = r.article_seq
WHERE   k.article_seq = $1
如果
类型
所有者
kbreview
中有多条记录,则第一个查询将失败,而第二个查询将返回
kbarticles
中的重复记录

如果
kbarticle
没有
类型
所有者
kbreviews
,则第一个查询将在相应字段中返回
NULL
,而第二个查询只会忽略该记录

如果
*.\u seq
字段似乎是
主键
字段,则不会有重复项,查询也不会失败;同样,如果
kbarticles
外键
类型
所有者
kbreview
的引用约束,则不能缺少行


但是,
JOIN
操作符为优化器提供了更多的位置:它可以使任何表处于前导位置,并使用更高级的
JOIN
技术,如
HASH JOIN
MERGE JOIN
,如果使用子查询,这些技术将不可用。

是的,该列有一个索引
kbreview\u article\u seq使用btree(article\u seq)在kbreview上创建索引kbreview\u article\u seq因此,基本上你是说我应该坚持使用
JOIN
s,因为从长远来看它们提供了更多的好处,并且真的可以忽略几毫秒?@Michael:正如我所说的,这些查询在逻辑上是不同的。只有当我提到的两个条件均为hold时,它们才是相同的:
*.\seq
字段是
主键
,并且您对
kbarticles
外键
约束,引用所有这些约束。如果它们没有(而且很可能没有,因为
kbreview.article_seq
似乎不是
主键,那么您应该选择您想要的。每篇文章你能有一篇以上的评论吗?如果可以,对于包含多个评论的文章,第一次查询将失败。
kbreview。文章\u seq
肯定不是主键。
kbreview
表中还有一列具有唯一主键。但是,
kbreview.article_seq
绝对是唯一的,不应该包含重复的值。我注意到我在该列上创建的索引没有唯一的约束,因此我现在已经修复了它。@Michael:一篇文章可以有多个或零个
类型
所有者
kbreview
记录吗?@Michael:那么你的查询是相同的,但是无论如何,最好使用
JOIN
。这些表有多少行?子查询在少量行上可以更快。。。你试过10000行或更多行吗?
QUERY PLAN

Nested Loop  (cost=0.00..32.39 rows=1 width=1293) (actual time=0.532..1.467 rows=1 loops=1)

  Join Filter: (k.owner = o.owner_seq)

  ->  Nested Loop  (cost=0.00..31.10 rows=1 width=1269) (actual time=0.419..1.345 rows=1 loops=1)

        ->  Nested Loop  (cost=0.00..22.82 rows=1 width=1249) (actual time=0.361..1.277 rows=1 loops=1)

              ->  Index Scan using article_seq_pkey on kbarticles k  (cost=0.00..8.27 rows=1 width=1241) (actual time=0.065..0.071 rows=1 loops=1)

                    Index Cond: (article_seq = 1511)

              ->  Seq Scan on kbreview r  (cost=0.00..14.54 rows=1 width=12) (actual time=0.267..1.175 rows=1 loops=1)

                    Filter: (r.article_seq = 1511)

        ->  Index Scan using types_type_seq_key on types t  (cost=0.00..8.27 rows=1 width=28) (actual time=0.048..0.055 rows=1 loops=1)

              Index Cond: (t.type_seq = k.type)

  ->  Seq Scan on owners o  (cost=0.00..1.13 rows=13 width=28) (actual time=0.022..0.038 rows=13 loops=1)

Total runtime: 2.256 ms
SELECT  article_seq, title, synopsis, body, lastmodified_date,
        (
        SELECT  type_id
        FROM    types
        WHERE   kbarticles.type = type_seq
        ),
        status, scope, images, archived, author, owner,
        (
        SELECT  owner_description
        FROM    owners
        WHERE   kbarticles.owner = owner_seq
        ),
        (
        SELECT  review_date
        FROM    kbreview
        WHERE   kbarticles.article_seq = article_seq
        )
FROM    kbarticles
WHERE   article_seq = $1
SELECT  k.article_seq, k.title, k.synopsis, k.body, k.lastmodified_date, t.type_id, k.status,
        k.scope, k.images, k.archived, k.author, k.owner, o.owner_description, r.review_date
FROM    kbarticles k
JOIN    types t
ON      k.type = t.type_seq
JOIN    owners o
ON      k.owner = o.owner_seq
JOIN    kbreview r
ON      k.article_seq = r.article_seq
WHERE   k.article_seq = $1