积极答复者
请大家帮忙分析下查询超时的原因,谢谢

问题
-
大家好,我们网站碰到一个数据库的问题,我自己除了会写点SQL,对数据库其他方面基本不怎么了解,所以请大家帮忙分析一下来解决这个问题,非常感谢。
我们用的是SQL Server 2008,这是我的表:
CREATE TABLE Orders
(
OrderID bigint NOT NULL ,
ProductID int NOT NULL ,
ProductName nvarchar(100) NOT NULL ,
ProductType smallint NOT NULL ,
ProductSalePrice decimal(8,3) NOT NULL ,
ProductParValue nvarchar(10) NOT NULL ,
ProductCostPrice decimal(8,3) NOT NULL ,
ProductSupplyRegion nvarchar(15) NULL ,
TargetAccount nvarchar(50) NULL ,
TargetAccountPassword varchar(20) NULL ,
TargetAccountType nvarchar(20) NULL ,
TargetAccountTypeName nvarchar(20) NULL ,
BuyAmount int NOT NULL ,
TotalSalePrice decimal(10,3) NOT NULL ,
TotalCostPrice decimal(10,3) NOT NULL ,
ServiceFee decimal(8,4) NOT NULL ,
Area nvarchar(30) NULL ,
AreaName nvarchar(30) NULL ,
Server nvarchar(30) NULL ,
ServerName nvarchar(30) NULL ,
Game nvarchar(30) NULL ,
GameName nvarchar(30) NULL ,
RechargeMode nvarchar(30) NULL ,
RechargeModeName nvarchar(30) NULL ,
RechargeInfo nvarchar(4000) NULL ,
StockMerchantID int NOT NULL ,
StockMerchantName nvarchar(30) NOT NULL ,
StockMerchantOrderID varchar(50) NOT NULL ,
SupplyMerchantID int NOT NULL ,
SupplyMerchantName nvarchar(30) NOT NULL ,
RechargeAccountUsername nvarchar(30) NULL ,
RechargeCard varchar(max) NULL ,
ManualOrderInfo nvarchar(1000) NULL ,
CustomerIP varchar(20) NULL ,
CustomerRegion nvarchar(30) NULL ,
State smallint NOT NULL ,
StateInfo nvarchar(1000) NULL ,
RefundState smallint NOT NULL ,
Source smallint NOT NULL ,
ResponseUrl varchar(100) NULL ,
ResponseTime datetime NULL ,
DealDateTime datetime NOT NULL ,
FinishDateTime datetime NULL
)
go
ALTER TABLE Orders
ADD PRIMARY KEY (OrderID ASC)
go
CREATE NONCLUSTERED INDEX [DealDateTime] ON [dbo].[Orders]
(
[DealDateTime] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
CREATE UNIQUE NONCLUSTERED INDEX [StockMerchantID_MerchantOrderID] ON [dbo].[Orders]
(
[StockMerchantID] ASC,
[StockMerchantOrderID] DESC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [SupplyMerchantID] ON [dbo].[Orders]
(
[SupplyMerchantID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
这是我的查询语句(用交易时间作为条件分页查询):
SELECT * FROM
(SELECT ROW_NUMBER() OVER(ORDER BY OrderID DESC) AS RowNumber, *
FROM Orders
WHERE 1=1 AND DealDateTime>='2012-12-14' AND DealDateTime<='2012-12-15') AS T
WHERE RowNumber BETWEEN 1 AND 50
问题:
在正式环境里,这个表一直在做频繁的增删查改操作(每天的新增订单有4万左右),总数据量为128万条,在执行这条查询语句的时候非常慢,一直超时,重新启动SQL Server后,略有改善,但查询速度仍然不理想,数小时后我删掉了这个表的一部分数据,还剩70多万条,这时候查询速度很快(1秒左右),两种情况下数据库的压力都差不多,CPU占用率一直在40%左右。
次日,我把正式环境的数据复制到本地的库里,共182万条数据,执行相同的查询,速度又感觉很快,本地电脑配置为2核2G内存,服务器配置为8核16G内存,当然本地没有频繁的增删查改操作。
我有点想不明白的是差了50多万条的数据量性能怎么会差那么多,不知道这是怎么回事?我想看些相关的资料来优化一下,但是现在不知道问题出在什么地方,从哪里开始呢?
如果有需要补充的我会跟帖,先谢了
答案
-
有时候快, 有时候慢有几种可能,
1数据的不同的造成的PLAN不同。
2你查询的时候有可能正好被阻塞。
我建议运行一下下面的语句,一次在快的时候运行,一次在慢的时候运行,然后把结果贴上来,来看看计划是否有不同,或者是否有阻塞。
set statistics profile on
go
set statistics time on
goT-SQL
set statistics time off
go
set statistics profile off
go
Please click the Mark as Answer button if a post solves your problem!- 已编辑 Michael CS 2013年1月10日 4:38
- 已标记为答案 se_zyt 2013年1月11日 1:46
全部回复
-
有时候快, 有时候慢有几种可能,
1数据的不同的造成的PLAN不同。
2你查询的时候有可能正好被阻塞。
我建议运行一下下面的语句,一次在快的时候运行,一次在慢的时候运行,然后把结果贴上来,来看看计划是否有不同,或者是否有阻塞。
set statistics profile on
go
set statistics time on
goT-SQL
set statistics time off
go
set statistics profile off
go
Please click the Mark as Answer button if a post solves your problem!- 已编辑 Michael CS 2013年1月10日 4:38
- 已标记为答案 se_zyt 2013年1月11日 1:46
-
先谢谢回复,发现了一个情况,我通过程序(C#,ADO.NET)执行SQL语句与在SSMS里直接执行SQL的性能差别很大,下午我再试验一下
那就是说你查询的时候用到查询参数/SQLparameter啦?
Please click the Mark as Answer button if a post solves your problem!- 已编辑 Michael CS 2013年1月10日 5:14
-
我只是猜测,不能确定。所以需要你快跟慢的时候的计划来确认。
如果确认是参数嗅探问题,可以尝试用OPTION (RECOMPILE) 来改善。
Please click the Mark as Answer button if a post solves your problem!- 已编辑 Michael CS 2013年1月10日 7:22
-
好像跟我的SQL有关系,改成下面这种以后,在本地测试速度跟之前的差不多,但是在正式环境上执行的时候速度明显快多了
SELECT *
FROM Orders
WHERE OrderID IN
(
SELECT OrderID
FROM (
SELECT ROW_NUMBER() OVER(ORDER BY OrderID DESC) AS RowNumber, OrderID
FROM Orders
WHERE 1=1 AND DealDateTime>'2013-01-10 00:00:00' AND DealDateTime<'2013-01-10 23:59:59'
) AS T
WHERE RowNumber BETWEEN 1 AND 15
)- 已编辑 se_zyt 2013年1月10日 8:26