2008-12-10 41 views
4

我正在進行分層數據庫結構的設計,該分層數據庫結構對包含產品的目錄建模(這與this question類似)。數據庫平臺是SQL Server 2005,目錄非常大(750,000個產品,超過4個級別的8,500個目錄部分),但相對靜態(每天重新加載一次),所以我們只關注READ性能。分層數據結構設計(嵌套集)

目錄分層結構的一般結構是: -

  • 1級第
    • 2級第
      • 3級第
        • 等級4組(產品有鏈接到這裏)

我們使用嵌套存儲的層級和存儲其存在在一個單獨的鏈接表該級別的產品設置模式。因此,簡化數據庫結構將是

CREATE TABLE CatalogueSection 
(
    SectionID INTEGER, 
    ParentID INTEGER, 
    LeftExtent INTEGER, 
    RightExtent INTEGER 
) 

CREATE TABLE CatalogueProduct 
(
    ProductID INTEGER, 
    SectionID INTEGER 
) 

我們確實有在一個更加複雜,我們有大約1000不同的客戶羣體可能會或可能不會看到所有目錄中的產品。因此,我們需要爲每個客戶羣維護一個單獨的「副本」,以便當他們瀏覽目錄時,他們只能看到他們的產品,而且他們也看不到任何空的部分。

爲了便於實現,我們在下面的部分中維護了一個層次結構的每個級別的產品數量表。因此,即使產品僅與層次結構的最低級別直接相關,它們也會一直統計在樹上。此表的結構是

CREATE TABLE CatalogueSectionCount 
(
    SectionID INTEGER, 
    CustomerGroupID INTEGER, 
    SubSectionCount INTEGER, 
    ProductCount INTEGER 
) 

所以,在這個問題 表現在層次結構的頂部水平很差。在所選目錄部分(以及所有子部分)中顯示「前10名」產品的一般查詢需要在1分鐘左右的時間內完成。在層次結構的較低部分,速度較快,但仍不夠好。

我已經在所有關鍵表上放置了索引(包括覆蓋索引),通過查詢分析器,索引調整嚮導等來運行它,但仍然無法使其執行得足夠快。

我想知道設計是否存在根本上的缺陷,或者是否因爲我們有這麼大的數據集?我們有一個合理的開發服務器(3.8GHZ Xeon處理器,4GB內存),但它只是不工作:)

感謝所有幫助

詹姆斯

+1

也許這會有助於向我們展示緩慢的SQL?我們可能會發現一些會造成瓶頸的東西。 – Jonathan 2008-12-10 10:53:09

回答

6

使用封閉臺。如果基本結構是具有字段ID和ParentID的父子,則封閉表的結構是ID和DescendantID。換句話說,封閉表是祖先後裔表,其中每個可能的祖先都與所有後代相關聯。如果需要,您可以包含一個LevelsBetween字段。閉包表實現通常包括自引用記錄,即,ID 1是LevelsBetween爲零的後代ID 1的祖先。

示例: 父/子
PARENTID - ID
1 - 2
1 - 3
3 - 4
3 - 5
4 - 6

祖先/後代
ID - DescendantID - LevelsBetween
1 - 1 - 0
1 - 2 - 1
1 - 3 - 1
1 - 4 - 2
1 - 6 - 3
2 - 2 - 0
3 - 3 - 0
3 - 4 - 1
3 - 5 - 1
3 - 6 - 2
4 - 4 - 0
4 - 6 - 1
5 - 5 - 0

表旨在消除遞歸連接。將遞歸連接的負載加載到您每天加載數據一次的ETL循環中。這將它從查詢中移開。

此外,它允許可變級別的層次結構。您將不會被卡在4.

最後,它允許您在非葉節點中插入產品。很多目錄在層次結構的更高層創建「雜項」存儲桶以創建附加產品的葉節點。由於中間節點包含在閉包中,因此不需要這樣做。

就索引來說,我會在ID/DescendantID上做一個聚集索引。

現在爲您的查詢性能。這需要大塊,但不是全部。你提到了一個「前十名」。這意味着對你沒有提及的一系列事實進行排序。我們需要細節來幫助調整這些。另外,這隻會得到葉級別的部分,而不是產品。至少,您應該在您的CatalogueProduct上有一個按SectionID/ProductID命令的索引。我會強制Section到Product連接是基於您提供的基數的循環連接。關於目錄部分的報告將轉到封閉表以獲取後代(使用聚集索引查找)。後代列表將被用於通過循環索引查找使用索引從CatalogueProduct獲取產品。然後,通過這些產品,您將獲得進行排名所需的事實。

0

您可能能夠解決客戶羣體問題的角色和treeId的,但你必須向我們提供查詢。

0

可能在每天加載後計算ProductCount和SubSectionCount?
如果數據一天只改變一次,那麼即使需要一些非規範化,計算這些數字也是值得的。

+0

是的,我們已經預先計算每天。這不是計算產品的問題,而是顯示選定部分中實際產品列表緩慢。 – James 2008-12-10 15:23:26

+0

您是否在重新加載數據後更新統計信息? 如果你的索引是好的(調整爲只讀使用),那麼它可能是你回來太多的數據?這是我可能接下來要看的一個領域。 TBH,在沒有看到架構和/或存儲過程的情況下幫助更多人將會相當困難。 – Bravax 2008-12-10 15:32:39