Rac*_*SQL 1 performance sql-server-2008 sql-server query-performance
编辑:
我知道这个问题已经结束,但我希望它会对某人有所帮助。
问题出在我们的磁盘( cluster )上。
使用 PerfMon,我可以创建一些计数器(磁盘读取和写入)并且读取计数器固定为 100%。
我看到以下等待
sp_WhoIsActive
:
PAGEIOLATCH_SH:Database_Name:1(*)
Run Code Online (Sandbox Code Playgroud)
我在这里看到一些帖子,说这个警告是因为高 I/O。SQL Server 联机丛书将 SQL 等待类型 PAGEIOLATCH_SH 定义为:
当任务正在等待 I/O 请求中的缓冲区的闩锁时发生。锁存请求处于共享模式。
和这个:
用户进程将请求一些当前不在缓冲区缓存中的数据。此时——SQL Server 将尝试分配一个缓冲区页——当数据从磁盘移动到缓冲区缓存时,在缓冲区上创建了一个独占的 PAGEIOLATCH_EX。同时从用户进程的角度在缓冲区上创建一个 PAGEIOLATCH_SH。
我创建了索引和统计信息,还使用了 SQL Server Profiler 来帮助我。
有什么办法可以改进查询吗?我怎样才能改进大量的处理ANDs
?
我们已经遇到这个问题大约一个星期了,我不知道该怎么办。
SELECT TOP 30 codCliente
FROM (
SELECT t1.CodCliente
, codcampo
, valor
, t1.chavealeat
FROM tblCliente AS t1 WITH(NOLOCK)
INNER JOIN tblClienteDetalhe AS t2 WITH (NOLOCK)
ON t1.codcliente = t2.codcliente
AND CodCampo IN (-1, 4)
WHERE codStatus IN(0)
AND t1.ChavePeriodo < getdate()
AND t1.CodStatusLigacao = 0
AND EXISTS (
SELECT codcliente
FROM tblclientedetalhe WITH (NOLOCK)
WHERE codcampo = 3
AND valor = '2'
AND codcliente = t1.codcliente
)
AND EXISTS (
SELECT codcliente
FROM tblclientedetalhe WITH (NOLOCK)
WHERE codcampo = 6
AND Convert(DateTime,Valor) BETWEEN '2015-03-01' AND '2015-03-31'
AND DateDiff(day,Valor,GetDate()) > 15
AND codcliente = t1.codcliente
)
AND NOT EXISTS (
SELECT 0
FROM tblPesquisa WITH (NOLOCK)
WHERE tblPesquisa.CodCliente = t1.CodCliente
)
AND EXISTS (
SELECT codcliente
FROM tblclientedetalhe WITH (NOLOCK)
WHERE codcampo = 4
AND valor = '161'
AND codcliente = t1.codcliente
)
) AS Cliente
PIVOT (
MAX(Valor)
FOR codCampo in ([4])
) AS PivotTable
WHERE ([4] = '161')
ORDER BY chavealeat;
Run Code Online (Sandbox Code Playgroud)
编辑1:
正如我在评论中所说的那样,此等待状态还有其他查询。我正在等待一项工作完成以确保这不是问题。
Han*_*non 10
这可能不会直接回答您的问题,但是您的查询中有多个潜在问题,我可以立即看到。
AND Convert(DateTime,Valor) BETWEEN '2015-03-01' AND '2015-03-31'
AND DateDiff(day,Valor,GetDate()) > 15
Run Code Online (Sandbox Code Playgroud)
你为什么要这样做CONVERT(DateTime, Valor)
?是Valor
不是DateTime
表中的一个类型?如果没有,那你就做错了。
在列 ( DateDiff(day, Valor, GetDate())
)上运行函数并将其与值进行比较使其不可 SARGable。试试这个,而不是:
AND Valor > DATEADD(DAY, -15, GETDATE())
BETWEEN (x and y)
可能不会像您认为的那样运作。您最好使用以下构造,因为它明确定义了您想要的精确日期范围。
WHERE Valor >= '2015-03-01T00:00:00' AND Valor < '2015-04-01T00:00:00'
WITH (NOLOCK)
不是一个更快的按钮!见http://blogs.sqlsentry.com/aaronbertrand/bad-habits-nolock-everywhere/和http://sqlperformance.com/2015/04/t-sql-queries/the-read-uncommitted-isolation-level为关于为什么在大多数情况下无法启动的绝佳细节。
归档时间: |
|
查看次数: |
7292 次 |
最近记录: |