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

     2023-04-15     124

关键词:

【中文标题】针对多对一关系优化 SQL 查询【英文标题】:Optimizing a SQL Query for a Many to One Relationship 【发布时间】:2011-09-23 14:16:57 【问题描述】:

我有两个具有多对一关系的表,我将它们称为 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。

【问题讨论】:

为什么不对一些适当大小的样本数据做一些性能测试? 在 SQL Server 2005 或更高版本中,选项 2 和 3 的处理方式相同。 要获得准确的答案,请分享您的 RDBMS。 在Oracle中依赖于统计,但是2和3可能是一样的。 猜测一文不值,你应该在足够大的样本数据上查看实际的查询执行计划。注意索引使用情况以及实际获取的行数和估计的行数之间的不匹配(大的不匹配表明您需要在表上创建/更新统计信息)。 【参考方案1】:

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

不了解数据库很难说更多:

但是:count(*) 通常比 count(names_field) 快 而且永远不会慢 count(distinct (afield)) 很慢

或者完全是别的什么?

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

是否取决于每个表的大小

是的,这很重要

或两个条件的复杂度

有可能

或者数据是否排序?

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

【讨论】:

+1 - 使用有限的信息,这几乎可以概括。 @EvilTeach,不在内部联接上下文中的主键上。 啊是的。这是一个一般性警告。【参考方案2】:

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

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

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

或者完全是别的什么?是取决于每张表的大小,还是两个条件的复杂程度,还是数据是否排序?

所有这些以及更多。

【讨论】:

【参考方案3】:

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

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

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

【讨论】:

不正确。 IN vs DISTINCT 将对处理时间产生非常很大的影响。 啊是的 - DISTINCT 通常是邪恶的,尤其是。从性能的角度来看。没有发现那个小块……但是,我确实认为 where 子句会产生很大的影响

JPA命名查询中的多对一关系

】JPA命名查询中的多对一关系【英文标题】:ManyToOneRelationinJPAnamedQuery【发布时间】:2017-01-2003:30:32【问题描述】:我是JPA的新手,现在研究如何通过manytoone关系连接两个表。我得到的实体来自数据库。我有两个表,分别命名为D... 查看详情

连接两个共享多对一关系的 SQL 表

】连接两个共享多对一关系的SQL表【英文标题】:JoiningTwoSQLTablesThatshareamanytooneRealtionship【发布时间】:2015-09-0815:27:05【问题描述】:您好,我有两张表,一张名为Team,另一张名为Schedule。Schedule表具有以下属性:id、away、home、d... 查看详情

java示例代码_使用JPA 2.0的CriteriaBuilder为多对一关系构造动态查询

java示例代码_使用JPA 2.0的CriteriaBuilder为多对一关系构造动态查询 查看详情

Q 查询中的重复结果涉及与模型的多对一关系

】Q查询中的重复结果涉及与模型的多对一关系【英文标题】:DuplicateresultsinQqueryinvolvingmanytoonerelationtoamodel【发布时间】:2013-08-3015:38:21【问题描述】:我有一个Car模型和一个带有Car对象的ForeignKey的Passenger模型。Car和Passenger模型... 查看详情

如何在 Doctrine 中建立多对一关系?

】如何在Doctrine中建立多对一关系?【英文标题】:HowtosetupaMany-To-OneRelationinDoctrine?【发布时间】:2019-01-2512:59:12【问题描述】:我正在Doctrine中设置一个新数据库,我想使用Many-To-One关系。数据库运行良好,但我无法对这些类使... 查看详情

建立多对一关系spring mvc

】建立多对一关系springmvc【英文标题】:setupamany-to-onerelationshipspringmvc【发布时间】:2011-06-1901:19:34【问题描述】:我正在尝试学习一些jsp以及spring框架。我的应用程序有2个sql表。“用户”和“位置”每个位置都属于一个用户。... 查看详情

休眠:多对一关系失败

】休眠:多对一关系失败【英文标题】:Hibernate:FailedManyToOnerelationship【发布时间】:2014-02-2605:59:58【问题描述】:我在尝试创建多对一映射时遇到以下错误Exceptioninthread"main"java.lang.ExceptionInInitializerErrorCausedby:org.hibernate.MappingExcep... 查看详情

与继承的单向多对一关系

】与继承的单向多对一关系【英文标题】:unidirectionalmanytoonerelationshipwithinheritance【发布时间】:2015-04-1501:44:04【问题描述】:我试图在休眠中映射classED和classTEL之间的多对一关系,但是当我在eclipse中尝试RunAs..Runonserver时出现以... 查看详情

django--orm表的多对一关系

多对一关系是什么Django使用django.db.models.ForeignKey定义多对一关系。ForeignKey需要一个位置参数:与该模型关联的类classInfo(models.Model):user=models.ForeignKey(other_model,on_del 查看详情

JPA:获取双向多对一关系

】JPA:获取双向多对一关系【英文标题】:JPA:fetchingbidirectionalmanytoonerelationship【发布时间】:2013-08-2820:59:15【问题描述】:我是JPA/JPQL方面的初学者,当我建立双向关系时,我在获取多对一关系时遇到了问题。这是JPQL:selectcfrom... 查看详情

java示例代码_处理JPA多对一关系

java示例代码_处理JPA多对一关系 查看详情

从多对一关系嵌入属性

】从多对一关系嵌入属性【英文标题】:Embeddingattributesfromamany-to-onerelationship【发布时间】:2016-02-1716:13:51【问题描述】:鉴于OracleDatabaseHRsampleschema中的COUNTRIES和REGIONS表:COUNTRIES(country_id,country_name,region_id)REGIONS(region_id,region_nam 查看详情

Rails 多对一关系聚合函数(组、计数)活动记录

】Rails多对一关系聚合函数(组、计数)活动记录【英文标题】:Railsmany-to-onerelationshipaggregatefunctions(group,count)activerecord【发布时间】:2017-02-0118:57:46【问题描述】:我有两个处于多对一关系的模型:classEventhas_many:commentsendclassCom... 查看详情

在同一事务中查找实体时,多对一关系始终为空

】在同一事务中查找实体时,多对一关系始终为空【英文标题】:ManyToOnerelationshipisalwaysnullwhenfindingentityinthesametransaction【发布时间】:2021-05-0701:01:07【问题描述】:我有一个与ModeratorEntity具有多对一关系的ConversationEntity@Entity@Tab... 查看详情

org.hibernate.PersistentObjectException 多对一关系

】org.hibernate.PersistentObjectException多对一关系【英文标题】:org.hibernate.PersistentObjectExceptionMany-to-onerelationship【发布时间】:2018-04-1613:04:54【问题描述】:运行应用程序时,我从MockData收到org.hibernate.PersistentObjectException错误。这是... 查看详情

一对多和多对一关系的区别

】一对多和多对一关系的区别【英文标题】:Differencebetweenone-to-manyandmany-to-onerelationship【发布时间】:2011-06-0320:31:33【问题描述】:一对多和多对一关系的真正区别是什么?它只是颠倒的,有点?除了这个主题之外,我找不到任... 查看详情

CRUD easyadmin 多对一关系

】CRUDeasyadmin多对一关系【英文标题】:CRUDeasyadminManyToOnerelation【发布时间】:2021-05-2719:25:59【问题描述】:我目前正在尝试制作一个包含2个实体的小型应用程序1个实体“Voiture”和一个实体“媒体”1voiture可以获得多个Medias。我... 查看详情

Laravel Eloquent GroupBy 多对一关系

】LaravelEloquentGroupBy多对一关系【英文标题】:LaravelEloquentGroupByManyToOneRelationship【发布时间】:2021-04-2105:45:00【问题描述】:我有下表结构:用户表idnamebalance1user142user223user32special_user表iduser_idstatus111221订单表iduser_idprovideramountdate... 查看详情