假设两个不同的表供应商和订单中有100M供应商和1B订单。我试图了解哪些查询在数据量很高时会表现得更好,尽管结果是相同的。我知道EXPLAIN PLAN会告诉逻辑计划和查询的成本,但我想了解哪个查询在简单的英语单词中运行得更快以及为什么。
SELECT s.supplier_id
FROM suppliers s
INNER JOIN (SELECT DISTINCT o.supplier_id FROM orders o) o
ON o.supplier_id = s.supplier_id
SELECT s.supplier_id
FROM suppliers s
WHERE EXISTS (SELECT * FROM orders o WHERE o.supplier_id = s.supplier_id)
SELECT s.supplier_id
FROM suppliers s
WHERE s.supplier_id IN (SELECT o.supplier_id FROM orders o)
SELECT s.supplier_id
FROM suppliers s
INTERSECT
SELECT o.supplier_id
FROM orders o
答案 0 :(得分:0)
这可能比你的例子更好:
SELECT s.supplier_id
FROM suppliers s
INNER JOIN orders o
ON o.supplier_id = s.supplier_id
子查询具有固有的执行成本,前三个示例使用这些成本。大型数据集的成本要高得多。
第4个示例基本上与我提供的示例相同,不同之处在于它将导致两个表的完整表扫描,以及执行交叉的临时表。
答案 1 :(得分:0)
查询1最可能的执行计划是:
优化包括加入行为; SQL引擎试图加入,索引或没有索引,因为它是查询中遇到的最常见的操作之一。如果订单上的供应商列被编入索引,我预计这将是最快的整体。缺点包括DISTINCT运算符。必要的是,由于订单与供应商之间存在一对多的关系,但最佳实现设置了一个哈希表,它与订单的数量呈线性关系,但增加了几层开销并且内存效率非常低,而天真的实现是N平方的复杂性,这对于如此大的源表是完全不合适的。
查询2的可能计划是:
此查询非常依赖于表和数据结构。如果对订单上的供应商列编制索引,则此查询将是行为中的NlogN,并且" N"问题将是供应商的数量,而不是订单的数量,将搜索空间减少一个数量级。如果它没有编入索引,那么供应商没有任何订单的最坏情况需要一个10亿条记录的表扫描来确定这一事实,根据订单表大小接近N平方的复杂性。
查询3的计划是:
最好的情况是,查询引擎将此简化为订单的索引供应商列上的联接。最糟糕的情况是,对于每个100米供应商,查询引擎最多可扫描10亿行。
查询4的计划是:
这是非常可怕的,几乎是最好的N平方复杂性;除非引擎做出假设,否则确实没有一种优化它的好方法。在做出这些假设时,有些SQL引擎比其他引擎更好。