相关疑难解决方法(0)

删除与截断

我试图更好地了解DELETETRUNCATE命令之间的差异。我对内部结构的理解大致如下:

DELETE-> 数据库引擎从相关数据页和输入该行的所有索引页中查找并删除该行。因此,索引越多,删除所需的时间就越长。

TRUNCATE -> 简单地删除所有表的数据页,使其成为删除表内容的更有效选项。

假设以上是正确的(如果不正确,请纠正我):

  1. 不同的恢复模式如何影响每个语句?如果有任何影响
  2. 删除时,是扫描所有索引还是仅扫描行所在的索引?我假设所有索引都被扫描(而不是搜索?)
  3. 命令是如何复制的?是否在每个订阅者上发送和处理 SQL 命令?还是 MSSQL 比这更智能一点?

sql-server database-internals

36
推荐指数
1
解决办法
2万
查看次数

为什么 DELETE 会对性能产生挥之不去的影响?

最后是一个测试脚本,用于比较@table 变量和#temp 表之间的性能。我想我已经正确设置了 - 性能计时是在 DELETE/TRUNCATE 命令之外进行的。我得到的结果如下(以毫秒为单位)。

@Table Variable  #Temp (delete)  #Temp (truncate)
---------------  --------------  ----------------
5723             5180            5506
15636            14746           7800
14506            14300           5583
14030            15460           5386
16706            16186           5360
Run Code Online (Sandbox Code Playgroud)

只是为了确保我是理智的,这表明 CURRENT_TIMESTAMP (aka GetDate()) 是在语句时使用的,而不是批处理时,因此 TRUNCATE/DELETE 与SET @StartTime = CURRENT_TIMESTAMP语句之间不应有交互。

select current_timestamp
waitfor delay '00:00:04'
select current_timestamp

-----------------------
2012-10-21 11:29:20.290

-----------------------
2012-10-21 11:29:24.290
Run Code Online (Sandbox Code Playgroud)

当使用 DELETE 清除表时,第一次运行和后续运行之间的跳转非常一致。我对DELETE 的理解缺少什么?我已经重复了很多次,交换了顺序,调整了 tempdb 的大小以使其不需要增长等。

CREATE TABLE #values (
  id int identity primary key, -- will be clustered …
Run Code Online (Sandbox Code Playgroud)

performance sql-server delete truncate sql-server-2012

20
推荐指数
1
解决办法
4094
查看次数

sql 2005 中的临时表缓慢下降

我在我们的生产 sql 服务器上遇到了一个问题,其中临时表对象需要很长时间才能删除(当使用小型同步删除时很明显)。我无法在其他 sql 服务器上重现这一点(同样指定使用相同数量的主轴来提供 tempdb 数据文件(拆分为相同数量的文件(每个物理核心 1 个))。在 SQL 2005 Enterprise (SP2 - 3042) 上。

更新:还有一个因素——看起来最有可能。该服务器上有 >500 个数据库。另一个大于 800 的服务器也运行这些 drop 很慢。那是我唯一拥有很多数据库的其他服务器。

第二次更新:重启有问题的服务器将允许立即执行 create 和 drop 语句。在接下来的几个小时内(在应用程序运行时),测试的性能会下降,直到达到(看起来是)平台期。我有一项在后台运行的工作,每 30 分钟测试一次。我会看看几天后的结果,看看执行时间是否相同。我认为他们会。

第三次更新:虽然没有一个正在执行的语句显示闩锁等待 CPU 资源,但使用 sp_whoisactive 我看到在 delta_interval = 30(秒)运行期间,运行查询 CPU_delta 报告大约 30,000(毫秒?),当我在执行期间观察 perf 时在执行期间似乎有一个核心的 CPU 峰值。这些在 16 个 cpu 盒上,因此当其他流量发生时通过 perfmon 看到可能有点困难,但它似乎在执行 drop 语句期间增加了 cpu 的价值。

在我测试过的大多数服务器上,创建和销毁 20 个具有唯一名称(一列,无行)的小型临时表的时间不到 20 毫秒。在一台服务器上需要> 5 秒。绝大多数 (>95%) 的时间都花在 drop 语句上。

在执行期间,没有显式等待,也没有报告阻塞,并且 perfmon 不显示 I/O 子系统上的任何数据或日志文件负载。

我查看了高峰和低使用时间,当大量表标记为销毁和低时。操作需要 5 秒左右来处理 20 个 drop …

sql-server

7
推荐指数
4
解决办法
2797
查看次数

如果不能使用 RESTORE,重置 SQL Server 数据库的最快方法是什么?

我有需要测试数据库才能运行的集成测试。
由于测试通常应该是独立的,所以我在每次测试开始时重置数据库。

我无法使用RESTORE,因为架构的某些部分(我无法控制)正在缓存连接,并且会在下次调用时因连接丢失而失败。

现在我正在创建一个快照,然后在每个表上调用DELETE+INSERT以将数据与快照同步。但是,每次重置需要 1 秒,这太多了(150 次测试 = 150 秒)。我有很多桌子,但它们几乎是空的,所以没有理由让它这么慢。

那么如何在不丢失连接的情况下在不到 1 秒的时间内用以前的版本替换数据库呢?

我的下一个想法是添加某种更改跟踪,因为每个测试只影响一些表,但这会使重置代码更加复杂。

更新:我添加了SET STATISTICS TIME ON,我得到了

SQL Server parse and compile time: 
   CPU time = 327 ms, elapsed time = 343 ms.
Run Code Online (Sandbox Code Playgroud)

对于我的重置 SP。我认为这是由于ALTER TABLE ... NOCHECK CONSTRAINT ALLSP 开始时的调用。我想知道在这种情况下是否可以抑制重新编译。

sql-server-2008 sql-server

7
推荐指数
2
解决办法
2878
查看次数