小编And*_*sch的帖子

SQL Server 缓存刷新和磁盘 I/O

我们正忙于对我们在 .NET 4.0 中开发并在后台运行 SQL Server 2008 R2 的 OLTP 系统进行负载测试。系统使用 SQL Server Service Broker 队列,它们的性能非常好,但我们在处理时遇到了一个特殊的趋势。

SQL Server 以极快的速度处理请求 1 分钟,然后增加约 20 秒的磁盘写入活动。下图说明了这个问题。

SQL OLTP 系统 - 性能计数器

Yellow = Transactions per second
Blue   = Total CPU usage
Red    = Sqlsrv Disk Write Bytes/s
Green  = Sqlsrv Disk Read Bytes/s
Run Code Online (Sandbox Code Playgroud)

在故障排除期间,我们尝试了以下方法,但模式没有任何重大变化:

  • 已停止 SQL Server 代理。
  • 杀死了几乎所有其他正在运行的进程(无 A/V、SSMS、VS、Windows 资源管理器等)
  • 删除了所有其他数据库。
  • 禁用所有对话计时器(我们不使用任何触发器)。
  • 从消息队列驱动的方法转向简单/粗略的表监控设计。
  • 使用从轻到重的不同负载。
  • 修复了所有死锁。

似乎 SQL Server 可能正在建立其缓存并以特定的时间间隔将其写入磁盘,但我无法在网上找到任何支持该理论的内容。

接下来,我计划将解决方案转移到我们的专用测试环境中,看看我是否可以复制该问题。在此期间的任何帮助将不胜感激。

更新 1 根据要求,附上一张图表,其中包括Checkpoint Pages/SecPage Life Expectancy和一些磁盘延迟计数器。

SQL OLTP 系统 - 性能计数器 - 检查点

看起来好像检查点(浅蓝线)是我们观察到的性能下降(黄线)的原因。^

磁盘延迟在处理过程中保持相对一致,页面预期寿命似乎没有任何明显影响。我们还调整了 SQL Server 可用的 ram 量,这也没有太大影响。将恢复模型从 …

performance sql-server service-broker

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

索引引用的表列

我想跨连接表的列进行搜索。以下查询的最佳索引配置是什么?

Table A
------------
Id
ValueA
-- Table A has many more columns

Table B
------------
Id
AId
ValueB
-- Table B has many more columns
Run Code Online (Sandbox Code Playgroud)

此刻,我对主键和非聚集索引(不包括任何列)列的聚簇索引AIdValueAValueB

SELECT *
FROM TableA a
INNER JOIN TableB b ON a.Id = b.AId
WHERE 
    a.ValueA LIKE 'SearchTerm%' OR
    b.ValueB LIKE 'SearchTerm%'
Run Code Online (Sandbox Code Playgroud)

更新 表 A 可能会遇到数百万个,而表 B 将只有数万个条目。

在现实世界中,表 A 将是一个交易列表,其中的值是某种交易引用。表 B 将是一个用户列表,其中的值可以是任何名称或任何其他描述性信息。

目前我们使用的是一个 ORM,它本质上会做一个SELECT *. 当然,这可以改变,但会对应用程序产生相当大的影响。

sql-server index-tuning string-searching

3
推荐指数
1
解决办法
115
查看次数

使用“OR”运算符时的 SQL Server 索引扫描

我们实现了一个 Google 风格的搜索,其中在前端触发去抖动后运行 SQL 查询。(我们知道 SQL 可能是错误的技术,但我在这里陷入了启动混乱。)查询:

SELECT 
    TOP(50) [Name], [Surname]
FROM 
    [dbo].[Clients]
WHERE 
    [Name] LIKE @SearchTerm + '%' OR
    [Surname] LIKE @SearchTerm + '%'
Run Code Online (Sandbox Code Playgroud)

这是一个相当大的表,所以我在两列上添加了两个非聚集索引以帮助加快速度:

CREATE NONCLUSTERED INDEX [IX_Patients_Name] ON [dbo].[Clients]
(
    [Name] ASC
)
INCLUDE([Surname]);

CREATE NONCLUSTERED INDEX [IX_Patients_Surname] ON [dbo].[Clients]
(
    [Surname] ASC
)
INCLUDE([Name]);
Run Code Online (Sandbox Code Playgroud)

我的想法是 SQL 会在两列上进行索引查找,但查询优化器似乎决定使用索引扫描

聚集索引查找

对于这个简单的用例,这可能不是一个真正的问题,但我们有更复杂的版本,具有多个连接等。

有什么方法可以优化此查询以使用搜索吗?

sql-server optimization nonclustered-index

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