簡體   English   中英

如何通過分組和篩選加快SQL Server查詢

[英]How to speed up SQL Server query with grouping and filtering

我有一個非常普通的任務來顯示我們的Web應用程序(asp.net + mssql)中的銷售歷史記錄。 我有一張出售交易表,例如:

 - SellerID (string)
 - Product PartNumber
 - Product ManufacturerName
 - ProductID (string uniq normalized PN+MN)
 - Date of sale
 - Price
 - Qty
 - Option 1
 - Option 2
 - Option 3

選項是一些特定的屬性(例如合同編號等)。

我需要顯示按productID分組的銷售數據,並匯總數量和金額。 我還需要提供一種通過SellerId,日期和選項進行過濾的功能。 所以用戶應該看表:

 - Part Number
 - Manufacturer Name
 - Sum(Qty)
 - Sum(Price)

用戶還可以按顯示的列進行排序和過濾,然后翻頁

目前,我們有大約500萬條銷售記錄,而具有這種分組,過濾和排序功能的“直接”查詢花費了太多時間(並且沒有想到該Web服務可以被多個並發用戶使用)。

為了使其運行更快,我們習慣於通過查詢中使用的所有條件來創建緩存鍵,並使用相同的方案(加上緩存鍵)將整個查詢結果復制到緩存表中。 但是存在一些缺點,例如高速緩存表的快速增長以及在高速緩存表中創建索引的困難(這會減慢插入速度)

我非常確定,此任務對於大多數與銷售有關的業務應用程序來說是非常常見和著名的。

人們如何解決所有這些問題?

UPD:我忘了提。

  1. 沒有插入銷售數據(我們過去通常每季度手動加載一次)

  2. 我當時在考慮olap,但從未真正使用過它。 使用olap是否有意義?

  3. 我們對SQL Server並沒有嚴格的限制,如果可以的話,我們可以使用任何其他數據庫

解決問題的方法取決於查詢和數據結構的混合。

對於您所描述的內容,自然格式將是星型模式,中間是事實表。 但是,事實表可能與您現在擁有的表非常接近。 區別在於記錄的大小。 事實記錄會將大部分“可讀”內容移至引用表,因此每條記錄都應盡可能小。 它可能看起來像:

  • SellerID-整數ID
  • ProductID-整數ID
  • 發售日期
  • 價錢
  • 數量
  • 選項1-smallint
  • 選項2-smallint
  • 選項3-smallint

像:

  • 產品零件號
  • 產品制造商名稱
  • 賣方名稱

將在參考表中。

這本身可能會使事實表減小到適合您的緩存的大小。

接下來,開始在其上建立索引。 您可能需要幾個索引,具體取決於過濾條件: (date, salesid, productid, option1, option2, option3)(productid, date)等。 我意識到索引確實需要對插入進行額外的工作。 影響取決於每天插入的數量。 對於決策支持系統,您應該可以忍受“數據滯后”,在該滯后中您可以定期更新數據。 批處理插入將有助於建立索引。

如果您需要實時報告,請考慮對數據進行分區,以便將最新數據存儲在一個較小的分區中。 分區索引較小,因此插入開銷應較小。

而且,如果您的需求確實很繁重-每分鍾進行大量實時更新,進行大量實時報告切片和切塊,以及大量需要完整歷史記錄的查詢-則需要更多的內存投入,以便表可以輕松放入記憶。 在此過程中,您可以優化中央數據結構,使其由id和數字量組成,並帶有保存其他數據的參考表。 主鍵上的聯接比存儲數據要快,否則將要大很多倍。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM