SQL 查询时间复杂度 - 连接与子查询
Posted
技术标签:
【中文标题】SQL 查询时间复杂度 - 连接与子查询【英文标题】:SQL Query Time Complexity - Join vs Sub Query 【发布时间】:2018-02-08 12:58:46 【问题描述】:我的问题是关于使用join
和sub-query
方法给出相同结果时的困境,
哪个更好更快? (纯粹就时间复杂度而言)
join
是否采用 O(M+N)
时间复杂度? sub-query
接受O(M*N)
吗?
我这样想错了吗?如果是,请纠正我。
这里,(M, N) 是两个表中的行数,组合得到的结果。
我正在寻找基于 SQL 标准的答案,而不仅仅是 mysql。
P.S - 我已经完成了this 问题及其所有答案。它本质上并不关心时间复杂度部分。
【问题讨论】:
MySQL(和其他 RDMS)中的查询计划模块非常复杂,以至于对这个问题唯一可以想到的答案是“视情况而定”。规划器可以将一些查询从子查询形式转换为连接形式。别人不能。索引和表基数都会影响查询计划者的决策。 关于 O(M+N) 和 O(M*N) 部分的任何提示? @O.Jones 一般来说连接性能更好..但正如 O.Jones 所建议的那样..“取决于” 在大多数现代数据库中,查询优化器足够聪明,可以在任何一种情况下创建最佳执行计划。有时,如果可能,子查询将与连接一样执行。 关于 O(M+N) 和 O(M*N) 部分的任何提示? (时间复杂度 w.r.t 行数)。我在一篇文章中读到,编译器可以在连接中使用散列技术,而在子查询中则不然。 @scaisEdge 【参考方案1】:join 需要 O(M+N) 时间复杂度吗?并且子查询需要 O(M*N) 吗? 我这样想有错吗?
是的,恕我直言,你这样想是错误的。 SQL 是声明性的。您使用它来声明您想要的结果,服务器会根据可用的索引和数据结构找出提供该结果的最佳方式——以满足您的查询。
几千年——真的! -- 开发人员的努力已经投入到找出各种算法、优化和技巧,以降低服务器用来满足查询的过程的复杂性。
随着数千年经验的积累,相关子查询和连接查询之间的性能差异变得不那么重要了。
由于特定原因,您的想法是错误的:您是在程序性地思考, 而不是声明性地思考。 例如,当您断言可以满足特定类型的查询时,@ 987654321@时间,您正在对用于满足它的程序进行假设。几代开发人员一直致力于让您的假设出错。
当然,可以创建具有病态性能特征的表、索引和查询。它一直在发生。但是有人修复了一个索引,问题就解决了。
【讨论】:
我能想到的最佳答案。!!感谢@O Jones 说明具体原因。现在明确了这个概念。 这当然是 100% 正确的……理论上。在实践中,有一些声明性模式被解析为 AST,查询优化器不容易将其转换为高性能执行。 相关子查询就是这样一个例子。出于这个确切原因,某些 RDBMS 甚至不支持该语法(例如,截至 2020 年 6 月的 Snowflake)【参考方案2】:据我了解性能应该是一样的。在您的表上应用正确的索引和集群更为重要。
【讨论】:
关于 O(M+N) 和 O(M*N) 部分的任何提示? (时间复杂度 w.r.t 行数)。我在一篇文章中读到,编译器可以在连接中使用散列技术,而在子查询中则不然。以上是关于SQL 查询时间复杂度 - 连接与子查询的主要内容,如果未能解决你的问题,请参考以下文章