Ashish Asked: 2014-05-08 04:11:55 +0800 CST2014-05-08 04:11:55 +0800 CST 2014-05-08 04:11:55 +0800 CST SQL Server 是否允许并行写入表和索引中的 INSERT? 772 如果我有一个有很多索引的表,并且我运行一个将行插入到表中的语句,SQL Server 是一次插入一个行,还是使用并行插入行? sql-server performance 1 个回答 Voted Best Answer Paul White 2014-05-12T11:10:03+08:002014-05-12T11:10:03+08:00 我运行一个向表中插入行的语句,SQL Server 是一次插入一个行,还是使用并行性? 在 SQL Server 2016 之前,单个T-SQL INSERT语句始终使用插入行并使用单个逻辑处理器维护关联的非聚集索引的执行计划。这回答了您问题的一个方面。 “一次插入一行”的问题需要一些解释。从根本上说,INSERT...SELECT执行计划中的数据修改始终作为一个或多个按顺序执行的一行一次的流进行操作。 也就是说,查询优化器通常可以在两种执行计划策略之间进行选择: 使用单个计划运算符将行插入基表和非聚集索引;或者 对每个非聚集索引、聚集索引或堆使用单独的计划运算符。 第一个选项意味着每一行都插入到基表中,并且所有非聚集索引都按顺序更新,然后再移动到下一行。这称为窄或每行插入策略。 第二个选项意味着在为每个非聚集索引执行相同操作之前,所有行都被插入到基表中(尽管一次仍然是一个),再次以串行顺序。这称为宽或按索引插入策略。 优化器为每个非聚集索引在窄策略和宽策略之间做出基于成本的选择,因此很常见的执行计划是在与基表相同的运算符中维护一些非聚集索引,而使用单独的运算符维护其他索引. Wide/per-index 策略还允许潜在的优化,例如按每个索引的键顺序对行集进行排序,以促进顺序访问模式。 您可以在我的博客文章“优化更改数据的 T-SQL 查询”中找到有关此内容和执行计划示例的更多详细信息。 有一个反馈建议允许并行维护非聚集索引。它在 Connect 上受到好评(后来迁移到新平台),但这个想法还没有实现。 虽然它仅限于单个处理器进行数据修改,INSERT...SELECT但可以在识别和创建要插入的数据的计划部分中使用并行性。从 SQL Server 2016 开始,INSERT...SELECT可以对堆执行并行插入。 为获得最佳插入性能,请检查您的查询是否满足最少记录操作的条件,可能需要跟踪标志 610。详细信息可在Data Loading Performance Guide中找到。 您可能还想使用其他允许使用多个进程进行并行插入(有一些警告)的 SQL Server 工具进行调查: SSIS(SQL 服务器集成服务) T_SQL BULK INSERT(来自文件) 实用bcp程序 SELECT INTO确实允许并行性(Server 2014+),但这要求该表在进程开始之前不存在,并且必须在之后添加任何非聚集索引。 如果您使用的是 Enterprise Edition,则分区表提供了优化批量插入的额外可能性。再次,请参阅数据加载性能指南了解详细信息。 我写的相关文章: 使用 INSERT…SELECT 到空聚集表中的最小日志记录 使用 INSERT…SELECT 和快速加载上下文的最小日志记录
在 SQL Server 2016 之前,单个
T-SQL INSERT
语句始终使用插入行并使用单个逻辑处理器维护关联的非聚集索引的执行计划。这回答了您问题的一个方面。“一次插入一行”的问题需要一些解释。从根本上说,
INSERT...SELECT
执行计划中的数据修改始终作为一个或多个按顺序执行的一行一次的流进行操作。也就是说,查询优化器通常可以在两种执行计划策略之间进行选择:
第一个选项意味着每一行都插入到基表中,并且所有非聚集索引都按顺序更新,然后再移动到下一行。这称为窄或每行插入策略。
第二个选项意味着在为每个非聚集索引执行相同操作之前,所有行都被插入到基表中(尽管一次仍然是一个),再次以串行顺序。这称为宽或按索引插入策略。
优化器为每个非聚集索引在窄策略和宽策略之间做出基于成本的选择,因此很常见的执行计划是在与基表相同的运算符中维护一些非聚集索引,而使用单独的运算符维护其他索引.
Wide/per-index 策略还允许潜在的优化,例如按每个索引的键顺序对行集进行排序,以促进顺序访问模式。
您可以在我的博客文章“优化更改数据的 T-SQL 查询”中找到有关此内容和执行计划示例的更多详细信息。
有一个反馈建议允许并行维护非聚集索引。它在 Connect 上受到好评(后来迁移到新平台),但这个想法还没有实现。
虽然它仅限于单个处理器进行数据修改,
INSERT...SELECT
但可以在识别和创建要插入的数据的计划部分中使用并行性。从 SQL Server 2016 开始,INSERT...SELECT
可以对堆执行并行插入。为获得最佳插入性能,请检查您的查询是否满足最少记录操作的条件,可能需要跟踪标志 610。详细信息可在Data Loading Performance Guide中找到。
您可能还想使用其他允许使用多个进程进行并行插入(有一些警告)的 SQL Server 工具进行调查:
T_SQL BULK INSERT
(来自文件)bcp
程序SELECT INTO
确实允许并行性(Server 2014+),但这要求该表在进程开始之前不存在,并且必须在之后添加任何非聚集索引。如果您使用的是 Enterprise Edition,则分区表提供了优化批量插入的额外可能性。再次,请参阅数据加载性能指南了解详细信息。
我写的相关文章: