您好我正在使用SQL Server 2008.在我的数据库中有一个名为MemberBusiness
的表。我想从该表中获取数据。
这是我的存储过程
SELECT BrokerId ,
RankId ,
MemberId ,
InstallmentId ,
PlanId ,
IntroducerId ,
Date ,
SelfAmount ,
UnitAmount ,
SpotAmount ,
ORBPercentageSelf ,
ORBPercentageUnit ,
ORBAmountSelf ,
ORBAmountUnit ,
IsSelfBusiness ,
Mode ,
InstallmentNo ,
PlanType ,
PlanName ,
CompanyId ,
CscId ,
Year ,
CreateDate ,
ModifideDate
FROM dbo.MemberBusiness AS mb
WHERE ( @CscId = 0
OR mb.CscId = @CscId
)
AND ( @CompanyId = 0
OR CompanyId = @CompanyId
)
AND BrokerId IN ( SELECT bt.BrokerId
FROM #brokerTable AS bt )
AND mb.Date >= @StartDate
AND mb.Date <= @EndDate
AND mb.RankId >= @FromRankId
AND mb.RankId <= @ToRankId
在MemberBusiness
表中,有大约16560352条记录。 SP以上给出了1300条记录,大约需要30秒才能执行,这对我来说是不可接受的。我使用了索引,但仍需要很长时间才能执行。怎么能更快地做到这一点?感谢。
答案 0 :(得分:0)
一些建议:
摆脱内部选择,取而代之的是这样的内连接:
SELECT BrokerId,... 来自dbo.MemberBusiness AS mb 将#brokerTable作为bt ON bt.BrokerID = mb.BrokerID加入 在哪里mb.CscID = @CscID ...
那些OR语句可能很慢......你可以摆脱它们或使用不同的查询进行联合吗?
确保您有一个大的单一索引,涵盖您正在比较的所有列,如下所示:
CREATE INDEX mySearchIndex ON MemberBusiness(CscId ASC,CompanyID ASC,BrokerId ASC,Date ASC,RankId ASC)
答案 1 :(得分:0)
您可以通过多种方式改进查询:
SQL:
IF @CscId = 0 AND @CompanyId = 0
BEGIN
SELECT mb.BrokerId,
mb.RankId,
mb.MemberId,
mb.InstallmentId ,
mb.PlanId ,
mb.IntroducerId ,
mb.Date ,
mb.SelfAmount ,
mb.UnitAmount ,
mb.SpotAmount ,
mb.ORBPercentageSelf ,
mb.ORBPercentageUnit ,
mb.ORBAmountSelf ,
mb.ORBAmountUnit ,
mb.IsSelfBusiness ,
mb.Mode ,
mb.InstallmentNo ,
mb.PlanType ,
mb.PlanName ,
mb.CompanyId ,
mb.CscId ,
mb.Year ,
mb.CreateDate ,
mb.ModifideDate
FROM dbo.MemberBusiness AS mb
INNER JOIN #brokerTable AS bt ON mb.BrokerId = bt.BrokerId
WHERE mb.Date >= @StartDate
AND mb.Date <= @EndDate
AND mb.RankId >= @FromRankId
AND mb.RankId <= @ToRankId
END
ELSE IF @CscId = 0 AND @CompanyId <> 0
BEGIN
SELECT mb.BrokerId,
mb.RankId,
mb.MemberId,
mb.InstallmentId ,
mb.PlanId ,
mb.IntroducerId ,
mb.Date ,
mb.SelfAmount ,
mb.UnitAmount ,
mb.SpotAmount ,
mb.ORBPercentageSelf ,
mb.ORBPercentageUnit ,
mb.ORBAmountSelf ,
mb.ORBAmountUnit ,
mb.IsSelfBusiness ,
mb.Mode ,
mb.InstallmentNo ,
mb.PlanType ,
mb.PlanName ,
mb.CompanyId ,
mb.CscId ,
mb.Year ,
mb.CreateDate ,
mb.ModifideDate
FROM dbo.MemberBusiness AS mb
INNER JOIN #brokerTable AS bt ON mb.BrokerId = bt.BrokerId
WHERE CompanyId = @CompanyId
AND mb.Date >= @StartDate
AND mb.Date <= @EndDate
AND mb.RankId >= @FromRankId
AND mb.RankId <= @ToRankId
END
ELSE IF @CscId <> 0 AND @CompanyId = 0
BEGIN
...
END
ELSE
BEGIN
...
END
然后是大部分,索引。您至少需要两个索引: - 一个群集
CREATE CLUSTERED INDEX [IX_MemberBusiness]
ON [dbo].[MemberBusiness]
(
RankId,
Date,
CompanyId,
CscId,
[The real ID of your table]
)
一个非群集
创建非集群索引[IX_MemberBusiness_nc] ON [dbo]。[MemberBusiness] ( RankId, 日期, CompanyId, CscId, [你桌子的真实身份证] ) 包括 ( [除索引中的所有字段外,所有字段中的字段] )
聚集索引必须包含您在其上进行范围查询的字段(即Date和RankId)。 非聚集必须包括“峰值”数据的字段(即BrokerId,CompanyId,CscId)。就像ids一样。
您可以通过使用SMSS中的查询计划,在索引设计方面做一些工作,方法是测试哪些字段与群集和非群集相关。
这项技术帮助我将项目的性能大幅提升了3倍。
让我知道它是否适合你。
答案 2 :(得分:-1)
可能这些可以帮助朝着正确的方向发展
@searchstring
保存搜索字符串的动态参数使查询动态化答案 3 :(得分:-2)
这就是调优和可扩展性。
弗里斯特: 使用查询分析器检查语句并创建索引和统计信息。不要忘记删除未使用的索引。尝试重新排列where子句,以便最佳地访问数据。您还可以使用QA为您创建索引和统计信息。
如果仍然要慢,请考虑硬件。 找到瓶颈,使用更多内存,更大的CPU或CPU,获得一些SSD,更快的网络。 尝试在群集中共享负载。