为什么 SELECT * INTO x FROM a JOIN b 比 SELECT COUNT(*) FROM a JOIN b & SELECT * INTO y FROM x 的总时间要长得多?

Why does SELECT * INTO x FROM a JOIN b take significantly greater time than total time of SELECT COUNT(*) FROM a JOIN b & SELECT * INTO y FROM x?

我有 2 个 table:ab。 Table a 有大约 100 万条记录,而 table b 有大约 50,000 条记录。非聚集索引在 a & b 中的每个列上定义。 2 table 是基于这些列连接的。查询如下:

SELECT * INTO x
FROM a JOIN b ON a.cola = b.colb

最终结果是大约 200 万条记录。查询大约需要 14 分钟才能完成。但是,如果我尝试执行 COUNT(*) 而不是 SELECT...INTO,查询将在一分钟内完成。

SELECT COUNT(*)
FROM a JOIN b ON a.col1 = b.col1

我假设剩下的 13 分钟是由于 I/O 操作。所以我 运行 另一个查询只是从 'x' 中获取先前插入的数据并插入到 'y'.

SELECT * INTO y
FROM x

这个查询用了 5 分钟来插入 200 万行数据。那么我的问题是第一个查询需要 14 分钟才能完成的原因是什么,而实际连接和独立插入同一组数据的总时间仅为 6 分钟。执行时间剩下8分钟的原因是什么?有什么办法可以减少这个时间吗?

我查看了第一个查询的实际执行计划。 >95% 的时间用在了 INSERT 操作中。 INSERT 操作只是按原样插入列——没有额外的逻辑(如计算、CAST、CASE...WHEN 等)。我的数据库已经处于 BULK_LOGGED 恢复模式,因此这些 SELECT...INTO 操作被最少记录。

是I/O操作。 JOIN 必须处理 所有 数据而不仅仅是行计数。您没有考虑这个处理时间。

鉴于 JOIN 必须完成的工作,额外的 read/write 数据似乎是正确的。