当我尝试通过另一个表的列从一个表中过滤数据时,我想使用INNER JOIN和相等运算符会更快,或者使用IN呢?

问题描述 投票:-2回答:2
虽然我试图获取所有从[email protected]接收消息的帐户。我想了解以下两个查询的性能。

SELECT * FROM account WHERE account_id in ( SELECT distinct account_id FROM message mes WHERE mes.sender = '[email protected]' )

SELECT distinct account.* FROM account acc INNER JOIN message mes ON mes.account_id = acc._id WHERE mes.sender = '[email protected]'

谢谢!

虽然我试图获取所有帐户,但这些帐户都收到了[email protected]的消息。我想了解以下两个查询的性能。在(...

sql postgresql join query-performance
2个回答
0
投票

X = account表中的1.000条记录(1000个用户)。

Y =每个帐户拥有100条消息。

    Z =每个用户拥有10个朋友。
  • T = message表中的10.000条消息。
  • 在第一个查询中,当我们从[email protected]表中搜索10.000条记录中的message电子邮件时。然后,我们将获得Foo发送给他们的10个account_id。现在,当我们在表用户中进行搜索时,我们将花费1.000时间来遍历每个帐户,并且将花10个时间来将当前acocunt_id与之前找到的列表10 account_id进行比较。
  • 根据数学,此查询的复杂度为:10.000 + 1.000 * 10 <=> T + X * Z

    [在第二个查询中,我们联接到表,结果表的长度期望为10.000(因为account表和message表之间的关系是一对多,所以每条消息仅属于一个帐户=>结果表的长度等于message表的长度),而查询WHERE仅需1次即可进行比较。

    根据数学,此查询的复杂度为:10.000 <=> T。

    但是我们看不到结果表的长度可能会扩展两倍大小。而且我无法计算JOIN函数的复杂度。这就是为什么我写这个问题。

    每个人都不喜欢我的问题。但是我真的很想知道。

  • 0
    投票
    理想情况下,您会在message (sender, account_id)上有一个索引。消息表本身甚至不必读取。在索引中查找发件人,然后获取所有匹配的帐户ID。这样,您就可以阅读账目了。没有索引,这可能会慢很多,但是仍然:读取消息表一次,获取不同的帐户ID,然后读取帐户。没关系。

    相反,通过加入,您可以将所有邮件与他们的帐户合并。这可能是一个很大的中间结果,必须对其进行排序以获取不同的行。昂贵的操作。而且即使DBMS非常擅长连接和排序,而且这样做速度非常快,它仍然可以对带有IN子句的简单查询使用相同的方法。由DBMS制定一个好的计划,而一个完美的DBMS会对两个查询提出完全相同的计划:-)

    我的建议:仅在对合并结果感兴趣时才加入。就您而言,您不是。您对符合某些条件的帐户感兴趣,因此请相应地编写查询。不要破坏您的查询,因为认为DBMS会使用另一种巧妙的方法。它甚至可能在当前的DBMS版本中执行此操作,并在下一个更新中停止执行此操作。保持查询尽可能可读。如果要在存在某些消息的帐户中使用WHEREEXISTSIN。这就是应该编写SQL的方式。
    © www.soinside.com 2019 - 2024. All rights reserved.