[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]的消息。我想了解以下两个查询的性能。在(...
X = account
表中的1.000条记录(1000个用户)。
Y =每个帐户拥有100条消息。
message
表中的10.000条消息。[email protected]
表中搜索10.000条记录中的message
电子邮件时。然后,我们将获得Foo发送给他们的10个account_id。现在,当我们在表用户中进行搜索时,我们将花费1.000时间来遍历每个帐户,并且将花10个时间来将当前acocunt_id与之前找到的列表10 account_id进行比较。 [在第二个查询中,我们联接到表,结果表的长度期望为10.000(因为account
表和message
表之间的关系是一对多,所以每条消息仅属于一个帐户=>结果表的长度等于message
表的长度),而查询WHERE仅需1次即可进行比较。
根据数学,此查询的复杂度为:10.000 <=> T。
但是我们看不到结果表的长度可能会扩展两倍大小。而且我无法计算JOIN函数的复杂度。这就是为什么我写这个问题。
每个人都不喜欢我的问题。但是我真的很想知道。
message (sender, account_id)
上有一个索引。消息表本身甚至不必读取。在索引中查找发件人,然后获取所有匹配的帐户ID。这样,您就可以阅读账目了。没有索引,这可能会慢很多,但是仍然:读取消息表一次,获取不同的帐户ID,然后读取帐户。没关系。相反,通过加入,您可以将所有邮件与他们的帐户合并。这可能是一个很大的中间结果,必须对其进行排序以获取不同的行。昂贵的操作。而且即使DBMS非常擅长连接和排序,而且这样做速度非常快,它仍然可以对带有IN
子句的简单查询使用相同的方法。由DBMS制定一个好的计划,而一个完美的DBMS会对两个查询提出完全相同的计划:-)
我的建议:仅在对合并结果感兴趣时才加入。就您而言,您不是。您对符合某些条件的帐户感兴趣,因此请相应地编写查询。不要破坏您的查询,因为认为DBMS会使用另一种巧妙的方法。它甚至可能在当前的DBMS版本中执行此操作,并在下一个更新中停止执行此操作。保持查询尽可能可读。如果要在存在某些消息的帐户中使用WHERE
和EXISTS
或IN
。这就是应该编写SQL的方式。