针对多对一关系优化SQL查询

时间:2011-09-23 14:16:58

标签: sql oracle optimization sql-optimization

我有两个表有多对一的关系,我称之为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>

或者它完全是另一回事?是否取决于每个表的大小,或两个条件的复杂程度,或者数据是否已排序?

编辑:数据库是Oracle。

3 个答案:

答案 0 :(得分:3)

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

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

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

  

或者它完全是另一回事?

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

  

是否取决于每个表的大小

是的,这起着重要作用

  

或两个条件的复杂性

可能

  

或者数据是否已排序?

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

答案 1 :(得分:0)

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

您真正需要做的是为每个查询生成执行计划并对其进行分析(我认为大多数流行的DBMS都有一个工具来执行此操作)。它将为您提供每个查询的成本值。

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

  

或者它完全是另一回事?是否取决于每个表的大小,或两个条件的复杂程度,或者数据是否已排序?

所有这一切以及更多。

答案 2 :(得分:-1)

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

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

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