2017-04-14 47 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數據庫