我正在寻找我们在应用程序中使用的存储过程的一些注释。它被召唤了很多,我认为还有改进的余地。我还希望看看为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之前调用一个插入到表中然后调用以在这个匹配中获得win%。
在使用显示执行计划几次之后,我确实添加了两个非聚集索引。
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]);
此表将获得百万行。目前它在120k左右。
我在每个团队的TeamHistoryMatchUps中添加了2条记录,结果为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 :(得分:1)
如果您不担心插入速度慢,我会说继续添加索引以获得更好的选择性能。
索引也应过滤结果为1的结果。
CREATE NONCLUSTERED INDEX [IX_TeamHistoryMatchUps_team_opp]
ON [dbo].[TeamHistoryMatchUps] ([Team],[Opp])
WHERE result=1
答案 1 :(得分: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= @TotalResult+@TeamResult
答案 2 :(得分:0)
答案是它取决于TeamHistoryMatchUps表中的记录数,以及每个列中有多少个不同的值。如果表中没有大量记录,查询优化器可能仍会创建一个涉及索引扫描的执行计划(它会读取索引中寻找匹配项的每个叶子记录)。这并不比全表扫描快得多。
如果有大量记录并且您在团队中搜索的值和opp索引将返回大约15%或更少的行,则查询优化器可能会选择通过以下方式使用索引索引寻求。在这种情况下,将会有性能提升。
答案 3 :(得分:0)
将sproc params重新声明为本地参数。它处理param嗅探,当WITH RECOMPILE没有帮助时,这也提高了性能(来源:待定)
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 DB上试过这个