我最近继承了一个包含大量存储过程的代码库。他们支持的系统遇到了许多我正在研究的性能问题。
许多存储过程都有这样的模式:
建立动态 SQL 查询以插入一堆记录,例如
DECLARE @sql VARCHAR(MAX)
SET @sql = 'INSERT INTO @tempTable
SELECT SomeColumn, SomeColumn2, SomeColumn3, etc FROM MyTable'
IF @someParam = [SomeValue]
SET @sql = @sql + 'WHERE SomeColumn = [SomeValue]';
IF @someOtherParam = [SomeOtherValue]
SET @sql = @sql + 'WHERE SomeOtherColum = [SomeOtherValue]';
Run Code Online (Sandbox Code Playgroud)执行这个动态sql
EXEC(@sql);
Run Code Online (Sandbox Code Playgroud)从临时表中选择并带入一堆附加信息以返回给客户端。
SELECT
...
FROM
@tempTable
INNER JOIN ...
Run Code Online (Sandbox Code Playgroud)我的即时想法是:
INSERT SELECT模式,所以表锁定更有可能是一个问题。我用这种方式重写了一些存储过程:
SELECT
...
FROM
MyTable
INNER JOIN ...
WHERE
(
@someParam != SomeValue
OR
SomeColumn …Run Code Online (Sandbox Code Playgroud) performance sql-server stored-procedures t-sql query-performance performance-tuning
我正在使用“数据库引擎优化顾问”分析查询。在此期间,数据库开始阻塞,长时间运行的查询并以重新启动实例结束。当我之后检查时,我发现drop index已经执行了一些命令。
drop index [dbo].[Profile].[_dta_index_Profile_7_1563152614__K15_K1]
Run Code Online (Sandbox Code Playgroud)
为什么会这样?我正在调整的查询不在配置文件表上!如何检查此索引之前是否已在系统中或在分析期间创建?
我运行了sp_Blitz,它指出了一个内存问题,说:
Memory Dangerously Low 服务器有 32755 MB 的物理内存,但只有 235 MB 可用。由于服务器内存不足,因此存在交换到磁盘的危险,这会降低性能。
服务器有32 GB RAM总,0-2 MB FreeRAM, 200 - 2376 Mb Available。
@@版本:Microsoft SQL Server 2008 R2 (SP2) - 10.50.4000.0 (X64) 2012 年 6 月 28 日 08:36:30 版权所有 (c) Microsoft Corporation Enterprise Edition(64 位),Windows NT 6.1(内部版本 7601:Service Pack) 1)
我看了一会儿性能计数器,看到了以下值:
Page Faults/s _Total ~ 1.200 Average, Max 18.000, regular Peeks up to 1500.
Page Faults/s sqlserver ~ 380 Average, Max 1600, regular Peeks …Run Code Online (Sandbox Code Playgroud) 是否可以通过 DAC 连接 MS SQL Server 2012 Express。从 SQL Server 2012 Enterprise 迁移到 MS SQL Server 2012 Express 后,存在一些性能问题。当我使用此 TSQL 签出时
select * from sys.dm_os_schedulers;
Run Code Online (Sandbox Code Playgroud)
调度未显示 DAC(专用管理员连接)调度程序 ID。
任何想法或建议将不胜感激。
performance sql-server-2012 windows-server dac performance-tuning
我有一个存储过程,它在几个表中插入一些记录。至少在几个表中,插入的记录数为 10000+。不过不超过15K。注意到3-5 mins这个程序来完成。也可以从多个用户会话中调用相同的过程,这会导致某些会话等待 20 分钟才能获得响应。我能做些什么来减少这个时间吗?
数据库恢复模式是完整的(无法更改),因此根据我的理解 sqlBulkCopy 在这里没有帮助。很想听听您对此的看法。
该表包含 15 列。其中5列是该表的外键。没有标识列,而是所有 5 个外键列组合的聚集索引。我在其他关键列上有几个索引。其余的列是十进制和 varchar(50)。不过我确实有一个 varchar(max) 列。
尝试获取查询或查询相同以供您参考。查询中最昂贵操作 (54) 的屏幕截图:
如果表的聚集索引是列组合而不是标识列,插入会受到影响吗?
基本上查询是'insert into this_table select from this table join with 5个其他表,这些表的主键是外键,以更新这些值。联接都在表之间的键上。我不介意发布查询,但是您是否还需要查询中涉及的所有表的架构?
EDIT2: 首先感谢你们所有人的回答、评论和想法。从中发生读取的对象结果是一个没有聚集索引的堆。修改它确实显着改善了读取操作,从而改善了整体。
我将 David Spillet 的答案标记为已接受,因为它提供了一种解决问题的有条理的方法。学到了一些关于发布问题的知识:)
也感谢飞盘的评论和回答。我知道我一直在修改问题:)
我们目前有一个 oninsert() 触发器设置,每次将行插入到表中时,都会触发更新查询以更新 3 个字段。这些字段是一个简单的计算,例如
field1update = (amt/12)*14
field2update = (amt/12)*16
field3update = (amt/12)*18
Run Code Online (Sandbox Code Playgroud)
触发器是足够的,但它有时会锁定该行,因此暂时无法立即访问它。我的问题是,如果将这些字段转换为(请原谅我的无知)计算列或计算列,我们会看到性能改进吗?
通常这是一个电子表格导入,一次插入大约 20,000 - 25,000 行。
performance sql-server t-sql sql-server-2008-r2 performance-tuning
CPU 利用率会定期达到 100%,当我检查 SP_who2 时,它显示大约 20000 个会话,其中大多数都在睡眠(也在使用 CPU)。
我认为 CPU 负载与睡眠会话有关
应用程序名称显示为 Microsoft JDBC。
大多数会话都将“SOS_SCHEDULER_YIELD”显示为 last_wait_type。重新启动 Windows Server 后,CPU 利用率已下降,但会话计数正在增加。
服务器有 32 个内核。
应用程序团队告诉他们正在使用一些“连接池”进行连接管理。
如何调查或解决睡眠会话的数量?
performance sql-server sql-server-2014 cpu performance-tuning
我一直听说sp_who2很快就会被弃用,不受支持。我们使用的是 SQL Server 2016 Enterprise。
什么是好的官方 Microsoft 替换项目或 DMV 哪个团队应该使用而不是sp_who2?
听说一个是sys.dm_exec_sessions?
我需要一个例程来有效识别哪些查询导致阻塞。这与我之前的问题如何找到仍然持有锁的查询有关?.
我知道网上有很多关于这方面的资料,但所有这些资料都是基于活动会话上的最后一条 SQL 语句很可能是获取锁的那个(因此产生了阻塞),这并不总是真的(在我的情况下,从来没有)。
我已将 设置blocking-process-threshold为 30 秒并开始分析阻塞进程报告 (BPR)。
当达到阈值时,每次发生阻塞时都会触发这些报告。
它包含有关阻塞 spid 和阻塞 spid 的信息。
通常,阻塞 spid 会在获取并持有资源(表、页或行)锁的语句之后运行几个语句:因此,不管报告内容如何,我仍然不知道究竟是哪个查询导致了该阻塞。
通常 SQL Server DMV 只显示每个 的最后一个 SQL 文本session_id,与活动锁(例如sys.dm_tran_locks)相关的 DMV也没有解决这个问题。
调整阻塞的查询在这里不是最好的方法:我们的应用程序全部基于嵌入在客户端代码中的动态 SQL,我们不使用存储过程,并且基于我目前看到的阻塞,所有阻塞的查询都被正确索引并写成。
我认为解决这个问题的一个选项是收集候选查询,这可能会产生阻塞,然后使用在 BPR 上收集的时间戳和 spid 查找此信息。你同意?如果是这样,您能否指出一种使用 xEvents 以尽可能少的开销来做到这一点的方法?
performance sql-server transaction locking blocking performance-tuning
是否有关于何时应用非聚集索引的一般选择性规则?
我们知道不要在位列 50/50 上创建索引。“具有 50/50 分布的行,它可能会给您带来很少的性能提升” SQL Server 中的索引位字段
那么在应用索引之前,SQL Server 中的查询应该有多大的选择性?SQL Server 指南中是否有一般规则?色谱柱中 25% 的平均选择性分布?10% 选择性?
这篇文章说明了大约 31%?索引的选择性应该如何?
performance ×10
sql-server ×9
index ×2
t-sql ×2
blocking ×1
cpu ×1
dac ×1
insert ×1
locking ×1
memory ×1
sp-blitz ×1
transaction ×1