2017-05-07 58 views
1

對於這個問題的目的,讓我們假裝我有如下表:SQL Server的全表掃描和負載

交易

  • 編號
  • 產品編號
  • 產品名稱
  • 城市
  • 國家
  • UnitCost
  • SellAmount
  • NumberOfTimesPurchased
  • 利潤(NumberOfTimesPurchased *(SellAmount - UnitCost))

基本上,在一百萬加行的單一反規範化的表。需要注意的是,只有兩列會更新:Profit和NumberOfTimesPurchased。進行銷售時,購買的NumberOfTimes將更新,新的利潤金額將重新計算。

現在,我需要對此表進行一些最小化的報告,該報告由聚合和分組查詢組成。舉例:

SELECT 
    City, AVG(UnitCost), AVG(SellAmount), 
    SUM(NumberOfTimesPurchased), AVG(Profit) 
FROM 
    Transaction 
GROUP BY 
    City 

SELECT 
    State, AVG(UnitCost), AVG(SellAmount), SUM(NumberOfTimesPurchased), 
    AVG(Profit) 
FROM 
    Transaction 
GROUP BY 
    State 

SELECT 
    Country, AVG(UnitCost), AVG(SellAmount), SUM(NumberOfTimesPurchased), 
    AVG(Profit) 
FROM 
    Transaction 
GROUP BY 
    Country 

SELECT 
    ProductId, ProductName, AVG(UnitCost), AVG(SellAmount), 
    SUM(NumberOfTimesPurchased), AVG(Profit) 
FROM 
    Transaction 
GROUP BY 
    ProductId, ProductName 

這些查詢很快:〜1秒。但是,我注意到,在負載下,性能顯着下降(當有20個併發請求時,性能顯着下降(從1秒到1分鐘),而我是猜測原因是每個查詢都執行全表掃描。

我試圖爲每個查詢使用索引視圖,但是由於每個視圖需要重建,所以我的更新語句的性能需要跳動。在同樣的說明中,我試圖爲每個查詢創建覆蓋索引,但是我的更新語句性能再次不能被接受。

假設全表掃描是罪魁禍首,我是否有任何實際的選擇來縮短查詢時間,同時保持更新性能在可接受的水平?

請注意,我不能使用列存儲索引(我使用的是更便宜的Azure SQL數據庫版本)。我還想遠離任何形式的彙總實施,因爲我需要立即提供數據。

最後 - 上面的例子不是我的表的完全準確的表示。我有20個左右不同的列可以「分組」,6列可以更新。沒有插入或刪除。

回答

1

由於查詢中沒有WHERE子句,數據庫引擎只能執行表掃描(或聚簇索引掃描,它實際上是同一件事)。如果覆蓋了包含查詢中所有列的索引,那麼引擎會優先選擇這些列。如果您的真實查詢具有WHERE子句,那麼將這些列作爲索引的前導列進行適當索引可能會對有所幫助。

但我認爲你的問題在別處。就併發性而言,你沒有投入足夠的錢。據主service tiers文檔,爲Azure的SQL數據庫的基本層是:

...在給定時間通常一個單一 積極運作支持。示例包括用於開發或測試的數據庫或小規模不常使用的應用程序。

因此,您可能需要考慮花費高級版來支持您的併發需求和列存儲索引,它們非常適合這種類型的查詢。爲了好玩,我創建了一個基於AdventureWorksDW2012的測試平臺,試圖重現您的問題,即here。查詢性能非常糟糕(> 20秒)。我會感到驚訝,如果你不是在您的門戶網站越來越DTU警告:

DTU Warnings

升級到標準(S0-S2)確實提高性能所以你應該嘗試。您可以考慮擴大繁忙查詢時間,並在不需要時關閉。

該表格看起來有點像事實表,所以您可能需要考慮將其重構爲事實/維度模型,然後在頂部使用Azure Analysis Services來實現該亞秒級性能。

巧合的是有你可以投票,使列存儲到標準層反饋項目:

https://feedback.azure.com/forums/217321-sql-database/suggestions/6878001-make-sql-column-store-feature-available-for-standa

最近的評論表明,它是「在工作隊列」截至2017年5月;

+1

對於這個應用程序,初始查詢被認爲是未過濾的,所以不會有'WHERE'子句(然而後續的查詢可能有它們)。 我一直在收到那些DTU警告 - 並且已經調整到S2來解決這個問題。但它並不能解決併發問題。 我會採用Analysis Services方法,但如果我沒有弄錯,這需要某種計劃彙總,不是嗎? 感謝您的幫助!希望標準層獲得專欄商店的支持,因爲我不相信高級層將成爲一種選擇 –