2017-04-14 46 views
0

我正在寻找我们在应用程序中使用的存储过程的一些注释。它被称为很多,我认为还有改进的空间。我还希望看看是否向Team和Opp添加索引将有助于SP。存储过程/表索引改进

我们正在Azure数据库上运行此操作。

该表的架构如下:

CREATE TABLE [dbo].[TeamHistoryMatchUps] (
    [Id]    UNIQUEIDENTIFIER DEFAULT (newid()) NOT NULL, 
    [Team]   NVARCHAR (100) NOT NULL, 
    [Opp]    NVARCHAR (100) NOT NULL, 
    [Result]   INT    NOT NULL, 
    [MatchResultTime] DATETIME2 (7) DEFAULT (getdate()) NOT NULL, 
    PRIMARY KEY CLUSTERED ([Id] ASC) 
); 

这里是SP:

CREATE PROCEDURE [dbo].[up_GetTeamPercentagev2] 
@Team NVARCHAR(100), 
@Opp NVARCHAR(100) 
AS 
begin 
set nocount ON 
declare 

@TotalResult INT, 
@TeamResult INT 


--Total Matchups 
Set @TotalResult = (SELECT count(*) FROM TeamHistoryMatchUps 
WHERE (Team = @Team OR Opp = @Team) AND (Team = @Opp OR Opp = @Opp) 
AND Result = 1) 

Set @TeamResult = (SELECT COUNT(*) FROM TeamHistoryMatchUps 
WHERE Team = @Team and Opp = @Opp 
AND Result = 1) 

SELECT (@TeamResult * 100/@TotalResult) AS Percentage 

exit_proc: 
end 

我要指出,我担心的是插入该SP被称为之前在桌子上插入一个插入物,然后随着时间的过去打电话来获得这场比赛的胜利。

在使用显示执行计划几次之后,我确实添加了两个非聚集索引。

GO 
CREATE NONCLUSTERED INDEX [[IX_MatchUps] 
    ON [dbo].[TeamHistoryMatchUps]([Result] ASC) 
    INCLUDE([Team], [Opp]); 
GO 
CREATE NONCLUSTERED INDEX [IX_MatchupsTeamOpp] 
    ON [dbo].[TeamHistoryMatchUps]([Team] ASC, [Opp] ASC) 
    INCLUDE([Result], [MatchResultTime], [MatchUpId]); 

该表格将获得百万行。目前它在12万左右。

我为每个团队添加了2条记录到TeamHistoryMatchUps中,结果为0或1.我试图保持它非常简单,以便上面的查询可以。

CREATE PROCEDURE [dbo].[up_GetTeamPercentage] 
    @Team NVARCHAR(100), 
    @Opp NVARCHAR(100) 
AS 
SELECT 
    SUM(SIGN(result)) * 100/COUNT(*) 
    AS Percentage 
    FROM TeamHistoryMatchUps 
    WHERE Team = @Team AND Opp = @Opp 

但认为较少的写入和更复杂的读取(在SP中)将是更好的方法。

+0

这个问题确实属于采用https: //codereview.stackexchange。com/ – Jens

+0

道歉应该删除和报告? – userStack

回答

1

如果你不担心插入缓慢,我会说继续前进,并添加索引更好的选择性能。

也是该指数应该过滤结果,其中结果为1

CREATE NONCLUSTERED INDEX [IX_TeamHistoryMatchUps_team_opp] 
ON [dbo].[TeamHistoryMatchUps] ([Team],[Opp]) 
WHERE result=1 
+0

我在问题中增加了更多细节。是的,我关心插件,因为它们在此之前就发生了。 – userStack

+0

指数帮助最大。谢谢您的帮助。 – userStack

+0

@userStack我很高兴我能帮助你。 –

0

我想这应该减少访问(在此期间,我想看看它的不可能性仅使用一个SELECT)。建议的索引应该有所帮助。

--Total Matchups 
SELECT @TeamResult = COUNT(*) FROM TeamHistoryMatchUps 
WHERE Result = 1 
    AND Team = @Team and Opp = @Opp 

SELECT @TotalResult = count(*) 
FROM TeamHistoryMatchUps 
WHERE Opp = @Team AND Team = @Opp 
AND Result = 1 

SET @TotalResult= @[email protected] 
0

的答案是,这取决于在TeamHistoryMatchUps表中的记录数,并在不同的值多少是在每个列。如果表中没有大量记录,查询优化器可能仍会创建一个涉及索引扫描的执行计划(该索引扫描会读取索引中的每个叶记录以查找匹配项)。这并不比全表扫描快得多。

如果在团队中搜索到很多记录和值,并且opp索引将返回约15%或更少的行,查询优化器可能会选择通过索引使用索引寻求。在这种情况下,会有性能改进。

+0

目前大约有12万条记录,我预计它会在一周内达到数百万。团队或Opp中大约有100个团队价值。 – userStack

+0

我想说,添加索引将是一个好主意。此外,Azure SQL还有一个“性能建议”屏幕,它将查看您的查询并建议应添加的索引。但是,您必须使用数据库才能收集信息并提出建议。 –

0

将sproc params重新声明为本地参数。它处理PARAM嗅探,这也提高了性能,重新编译的时候没有帮助(来源:TBD)

CREATE PROCEDURE [dbo].[up_GetTeamPercentagev2] @Team NVARCHAR(100), @Opp NVARCHAR(100) AS begin set nocount ON declare

@localTeam NVARCHAR(100), @localOpp NVARCHAR(100), @TotalResult INT, @TeamResult INT

Set @Team = @localTeam SET @Opp = @localOpp

--Total Matchups Set @TotalResult = (SELECT count(*) FROM TeamHistoryMatchUps WHERE (Team = @localTeam OR Opp = @localTeam) AND (Team = @localOpp OR Opp = @localOpp) AND Result = 1)

Set @TeamResult = (SELECT COUNT(*) FROM TeamHistoryMatchUps WHERE Team = @localTeam and Opp = @localOpp AND Result = 1)

SELECT (@TeamResult * 100/@TotalResult) AS Percentage

exit_proc: end

***从未尝试过这个在Azure数据库