Stu*_*ler 36 sql-server database-internals
我试图更好地了解DELETE和TRUNCATE命令之间的差异。我对内部结构的理解大致如下:
DELETE-> 数据库引擎从相关数据页和输入该行的所有索引页中查找并删除该行。因此,索引越多,删除所需的时间就越长。
TRUNCATE -> 简单地删除所有表的数据页,使其成为删除表内容的更有效选项。
假设以上是正确的(如果不正确,请纠正我):
Pau*_*ite 60
DELETE -> 数据库引擎从相关数据页和输入该行的所有索引页中查找并删除该行。因此,索引越多,删除所需的时间就越长。
是的,尽管这里有两种选择。可以由执行基表删除的同一运算符逐行从非聚集索引中删除行。这称为窄(或每行)更新计划:

或者,非聚集索引删除可以由单独的操作员执行,每个非聚集索引一个。在这种情况下(称为广泛或每索引更新计划),完整的操作集存储在工作表(eager spool)中,然后每个索引重放一次,通常按特定非聚集索引的键显式排序以鼓励顺序访问模式。

TRUNCATE -> 简单地删除所有表的数据页,使其成为删除表内容的更有效选项。
是的。 TRUNCATE TABLE由于多种原因,效率更高:
不同的恢复模式如何影响每个语句?有什么影响吗?
删除总是完整记录(删除的每一行都记录在事务日志中)。如果恢复模式不是FULL,则日志记录的内容会有一些小的差异,但这在技术上仍然是完整的日志记录。
删除时,是扫描所有索引还是仅扫描行所在的索引?我假设所有索引都被扫描(而不是搜索?)
删除索引中的一行(使用前面显示的窄更新计划或宽更新计划)始终是键访问(搜索)。为删除的每一行扫描整个索引将是非常低效的。让我们再看一下之前显示的每个索引更新计划:

执行计划是需求驱动的管道:父操作符(左侧)通过一次向子操作符请求一行来驱动子操作符执行工作。Sort 运算符是阻塞的(它们必须在生成第一个已排序的行之前使用它们的全部输入),但它们仍然由请求第一行的父级(索引删除)驱动。索引删除一次从完成的排序中拉出一行,更新每一行的目标非聚集索引。
在广泛的更新计划中,您经常会看到基表更新操作符将列添加到行流中。在这种情况下,聚集索引删除将非聚集索引键列添加到流中。存储引擎需要此数据来定位要从非聚集索引中删除的行:

命令是如何复制的?是否在每个订阅者上发送和处理 SQL 命令?或者 SQL Server 是否比这更智能?
不允许对使用事务复制或合并复制发布的表进行截断。如何复制删除取决于复制的类型及其配置方式。例如,快照复制只是使用批量方法复制表的时间点视图 - 不会跟踪或应用增量更改。事务复制的工作原理是读取日志记录并生成适当的事务以将更改应用于订阅者。合并复制使用触发器和元数据表跟踪更改。
相关阅读:优化更改数据的 T-SQL 查询
| 归档时间: |
|
| 查看次数: |
21863 次 |
| 最近记录: |