Top 2 很快出结果 Top 3 很久很久啊
select top 3 * from NotificationHistoryData.dbo.PresenceMissingRecord nolock
select top 2 * from NotificationHistoryData.dbo.PresenceMissingRecord nolock
出现这样问题的原因是?
[最优解释]
你每次都是这样?看看是不是有阻塞或者有什么瓶颈》。。。
[其他解释]
你是每次执行都会这样的现象?还是偶尔?有没有试过在基本上没人用数据库的时候查?
[其他解释]
那可能行比较大的就是阻塞了,特别是其他的语句操作时,速度不够快,导致锁表,你的查询就只能等待。这在几千万表上操作时尤为突出,在你觉得很慢的时候试试一下语句:
select * from sys.sysprocesses where blocked<>0
如果有数据且刷新了几次都还在,且那个就是你执行的语句,证明有阻塞。
[其他解释]
1、优化语句,你的select top 3 * from NotificationHistoryData.dbo.PresenceMissingRecord nolock如果不加where的话,其实还是全表扫描,8000万你可以想象一下。
2、找出阻塞的语句:select * from sys.sysprocesses where blocked<>0这个语句中有个blocked的字段,找出这个值,然后用dbcc inputbuffer(这个值),可以看到你的select top 3 * from NotificationHistoryData.dbo.PresenceMissingRecord nolock是被什么阻塞了。然后优化这个语句。
不过我奇怪的是你都nolock了怎么还会阻塞?
[其他解释]
直接郁闷了
[其他解释]
现在这个表有8千万数据了
[其他解释]
不是每次,以前都还可以的。现在只执行一个TableA INNER JOIN PresenceMissingRecord 删除 A 中记录的操作
-- Set the database where the stored procedure is located
USE StatusData
GO
-- Drop older version if it exists
IF OBJECTPROPERTY(OBJECT_ID(N'dbo.chgDMRForLatestDate'), N'IsProcedure') = 1
DROP PROCEDURE dbo.chgDMRForLatestDate
GO
-- Name: chgDMRForLatestDate
-- Purpose:
-- Location: StatusData
-- Authorized to: rl_DataUpload
-- Last Update:
-- Parameter:
-- Input
-- 1. p_EffectiveDate SMALLDATETIME NOT NULL
-- Output:
-- None
-- Result Set:
-- None
--
-- Return: @@ERROR
--
-- Sample Execution:
--
-- Author: Sean Liao
-- Create date: 2011-05-12
-- Revisions:
-- 2011-08-5 Yong Feng: use NotificationHistoryData.dbo.PresenceMissingRecord to simplify the SP
--
CREATE PROCEDURE dbo.chgDMRForLatestDate
@p_EffectiveDate SMALLDATETIME,
@p_ReportCategory TINYINT
AS
SET NOCOUNT ON
DECLARE @l_Err INT,
@l_Msg VARCHAR(500),
@l_Id NVARCHAR(15),
@l_ProcName VARCHAR(30),
@l_ProcDB VARCHAR(30),
@i TINYINT,
@r_affectedRows INT
-- Initialize error handle-related constants
SET @l_Id = ''
SET @l_ProcName = OBJECT_NAME (@@PROCID)
SET @l_ProcDB = DB_NAME()
-- Business logic
BEGIN TRY
;WITH latest AS
(
SELECT Id,ReportTypeId ,MAX(KeyDate) AS LatestDate
FROM NotificationHistoryData.dbo.PresenceMissingRecord nd WITH(NOLOCK)
GROUP BY Id, ReportTypeId
)
UPDATE dmr
SET dmr.LatestDate =latest.LatestDate
FROM DataMissingReport dmr
INNER JOIN latest
ON dmr.InvestmentId=latest.Id AND dmr.ReportTypeId=latest.ReportTypeId
WHERE EffectiveDate=@p_EffectiveDate
SET @r_affectedRows= @@ROWCOUNT
SELECT @r_affectedRows;
END TRY
-- Exception handle
BEGIN CATCH
-- Rollback transaction if needed
IF @@TRANCOUNT > 0
BEGIN
ROLLBACK TRAN
END
-- Log error message
SET @l_Msg = 'Number: ' + CONVERT(VARCHAR, ERROR_NUMBER()) + CHAR(10) +
'Line: ' + CONVERT(VARCHAR, ERROR_LINE()) + CHAR(10) +
'Severity: ' + CONVERT(VARCHAR, ERROR_SEVERITY()) + CHAR(10) +
'State: ' + CONVERT(VARCHAR, ERROR_STATE()) + CHAR(10) +
'Procedure: ' + ISNULL(ERROR_PROCEDURE(), '') + CHAR(10) +
'Message: ' + ERROR_MESSAGE()
SET @l_Err = ERROR_NUMBER()
-- Store error and raise error
EXECUTE dbo.sp_LogError @l_Err, @l_Msg, @l_Id, @l_ProcName, @l_ProcDB
RAISERROR(@l_Msg, 18, 1)
RETURN @l_Err
END CATCH
RETURN @@ERROR
GO
--GRANT EXECUTE ON dbo.chgDMRForLatestDate TO rl_DBOwner
GRANT EXECUTE ON dbo.chgDMRForLatestDate TO rl_DataUpload
--GRANT EXECUTE ON dbo.chgDMRForLatestDate TO rl_DataDownload
GO
FROM NotificationHistoryData.dbo.PresenceMissingRecord nd WITH(NOLOCK)
GROUP BY Id, ReportTypeId
)
--UPDATE dmr
-- SET dmr.LatestDate =latest.LatestDate
select *
FROM DataMissingReport dmr
INNER JOIN latest
ON dmr.InvestmentId=latest.Id AND dmr.ReportTypeId=latest.ReportTypeId
WHERE EffectiveDate=@p_EffectiveDate
执行这个慢不?
[其他解释]
你在TableA INNER JOIN PresenceMissingRecord ,你看看top 3的时候,TableA 是不是有很多行数据含有第三个值。
按照你现在的情况,我估计前两个值在TableA 中很少,或者没有,而第三个值很多。这个和是不是使用nolock 没什么关系,而且你也提到,之前速度还行,只是现在慢了。
如果是上面的情况,那你就需要在TableA 中增加合适的index了。
[其他解释]
你看看执行TOP2和TOP3的执行计划有什么不一样。曾经碰到过一个问题执行TOP 10非常快,但是TOP1跑不出来,后来查了一下发现两个使用的执行计划完全不同,将TOP1的执行计划改一下就好了,不知道你的是不是同样的问题。