两个索引上的内部联接的 Big-Oh 性能

Posted

技术标签:

【中文标题】两个索引上的内部联接的 Big-Oh 性能【英文标题】:Big-Oh Performance of an Inner Join on Two Indexes 【发布时间】:2013-05-11 13:25:32 【问题描述】:

我正在尝试找出以下查询的 Big-Oh 性能:

SELECT * 
FROM table1 INNER JOIN table2 ON table1.a = table2.b
GROUP BY table1.a

table1.a 是表的主键。 table2.b 上有一个非唯一索引。

我的想法是因为每个索引都可以在 O(log n) 中搜索,那么这个查询在 O(log n * log m) 中执行,其中 n 是表 1 中的行数,m 是表中的行数表 2。

我们将不胜感激。

【问题讨论】:

在发帖前写一个有效的查询。这不是有效的 ANSI/ISO SQL 语法,即使在 mysql 中也会抛出错误(ONLY_FULL_GROUP_BY setting) 【参考方案1】:

你的想法有点不对劲。可以在 O(log n) 中搜索索引以进行单个查找。您的查询可能是其中的“n”或“m”个。

让我假设查询通过扫描一个表并查找另一个表中的值将两个表连接在一起来进行处理。然后它对order by 进行基于排序的聚合。

查询的“匹配”部分是较大的:

O(n log m) O(m log n)

这假设查询引擎决定扫描一个表并在另一个表的索引中查找值。

要继续,一旦您查找值,您需要在页面中为您使用索引的表获取数据。获取数据在技术上是 O(n)。到目前为止,我们的估计是 O((n log m) + n + )。

对于排序后跟扫描的聚合应该是 O(n log n)。但是,您有多少条记录用于聚合?您可以有多达 n*m 匹配到联接。或者,少至 0(它是一个内连接)。

这是 big-O,它是一个上限。所以,我们必须使用更大的估计。这导致聚合的 O((n*m)log(n*m)) ,这将支配其他术语。大 O 将是 O((n*m) log(n*m))。

【讨论】:

你说“匹配”的那块是“大”的。你不是说“更小”的吗?如果一个表有 2 行,而另一个有 200 万行,则查询优化器应该选择小表,然后对较大的表执行查找。对吗? @BMiner 。 . . "big oh" 是上限,这就是它更大的原因。 对不起,你是什么意思?您是说(对于“Big oh”),您不能假设查询优化器算法会选择“更便宜”的路线来计算连接?【参考方案2】:

查询的性能取决于 SQL 语句在内部的执行方式。

也许您可以在此处查看 EXPLAIN(对于 MySQL:http://dev.mysql.com/doc/refman/5.1/en/explain.html)以获取有关如何执行查询的更多信息,因为这可以产生比查看 Big-Oh 更准确的结果。

顺便说一句:如果您真的在寻找 Big-Oh,Gordon Linoff 的答案看起来不错!

【讨论】:

以上是关于两个索引上的内部联接的 Big-Oh 性能的主要内容,如果未能解决你的问题,请参考以下文章

内部联接与内部联接(SELECT . FROM)

内部联接和简单联接之间是不是有任何性能差异? [复制]

SQL Server 2005 - 内部联接的顺序

外部联接中的内部联接导致性能不足,有啥不同的方法?

LIKE sqldf 上的内部联接

联接表上的条件比参考上的条件快