2

我有两个具有多对一关系的表,我将它们称为 Parent_Table 和 Child_Table (即父母有零个或多个孩子,但孩子只有一个父母)。我需要计算至少有一个孩子满足某些条件的父母的数量。哪个查询是最佳的?

选项1(很确定不是这个)

SELECT COUNT(DISTINCT(pt.ID)) 
FROM PARENT_TABLE pt
JOIN CHILD_TABLE ct
ON pt.ID =  ct.PARENT_ID
WHERE <parent meets some condition>
AND <child meets some condition>

选项 2

SELECT COUNT(pt.ID)
FROM PARENT_TABLE pt
WHERE pt.ID in
(
SELECT ct.PARENT_ID
FROM CHILD_TABLE ct
WHERE <child meets condition>
)
AND <parent meets some condition>

选项3(我猜是最快的)

SELECT COUNT(pt.ID)
FROM PARENT_TABLE pt
WHERE EXISTS
(
SELECT 1
FROM CHILD_TABLE ct
WHERE ct.PARENT_ID = pt.ID
AND <child meets condition>
)
AND <parent meets some condition>

还是完全是别的东西?它取决于每个表的大小,还是两个条件的复杂性,或者数据是否排序?

编辑:数据库是甲骨文。

4

3 回答 3

3

第一个查询很慢,其他查询应该在大多数数据库上运行得很快。

在不了解数据库的情况下,很难说更多:

但是:count(*) 通常比 count(names_field) 快,并且从不慢
count(distinct (afield)) 很慢

还是完全是别的东西?

这取决于数据库和数据库的确切版本。

是否取决于每张桌子的大小

是的,这很重要

或两个条件的复杂性

可能的

或者数据是否排序?

如果您想要快速选择,则必须对用于连接的所有字段进行索引。
并且 where 子句中使用的所有字段都必须是索引的或低基数的。

于 2011-09-23T14:30:43.900 回答
0

对我来说,第一个似乎是最好的,因为它最容易阅读,但这显然不能回答你的问题。

你真正需要做的是为每个查询生成执行计划并分析它们(我认为大多数流行的 DBMS 都有一个工具可以做到这一点)。它将为您提供每个查询的成本值。

如果你不能这样做,我猜你可以多次运行查询并比较执行时间。

还是完全是别的东西?它取决于每个表的大小,还是两个条件的复杂性,或者数据是否排序?

所有这些以及更多。

于 2011-09-23T14:26:06.387 回答
-1

正如评论者所说,回答这个问题的最佳方法是运行查询和测量。

但是,一般来说,数据库引擎非常非常有效地优化连接 - 我很确定您会发现这 3 个查询之间几乎没有区别,并且查询优化器完全有可能将它们全部变成相同的基本查询(2 和 3是等价的)。

到目前为止,对查询影响最大的将是“孩子满足某些条件”和“父母满足某些条件”子句。我会专注于优化这一点。

于 2011-09-23T14:28:37.477 回答