具有唯一標識符和日期的表上的聚集索引和主鍵
我有帶有唯一遞增 ID 和(訂單創建)日期的訂單表。這個表很大很寬(500 萬行,50 列,其中 10 列是 FK ID)。例子:
CREATE TABLE Orders As ( ID int UNIQUE AUTOINCREMENT (1,1), DATE datetime, --This is SQL Server 2005, so no [date] data type OrderStatus char (2), ClientID int ... )
我把這張表作為昨天生產表的副本。表(作為整個數據庫)用於報告目的,因此是只讀的。
第1部分
我有兩個非常常見的案例:
- 80%(或更多)的查詢
DATE
在子句中有列WHERE
,因為使用者需要特定業務日期的數據。在這裡,我想在 DATE 創建聚集索引。
- 40%-60% 的查詢
OrderID
將JOIN
Orders 表用於其他表,其中包含有關訂單詳細資訊(產品、供應商、付款、預訂等)的資訊。在這裡,我想在 OrderID 上創建聚集索引。
第2部分
我可以為這兩種情況使用一個 CI 嗎?索引 (ID, DATE) 不適用於
WHERE
子句。索引 (DATE,ID) 不適用於ID
僅 on 或ID
in的連接WHERE
抓住。我們知道 DATE 和 ID 一樣是增量的。昨天任何情況下,價值較高的ID都不能按原樣出現
AUTOINCREMENT
。問題。有沒有辦法告訴 SQL Server CI (DATE, ID) 將按順序對所有日期排序?
我目前唯一的解決方案是創建非聚集覆蓋索引(ID,DATE),但它不是最理想的。
我已經搜尋了一段時間,但找不到任何東西。如果有更高版本的 SQL Server 的解決方案,我也會對此感興趣。
更新
我知道聚集索引基礎知識。請注意,數據庫對使用者處於只讀狀態。
從邏輯上講,您可以忽略 (Date, ID) 索引中的 Date 列,而不會造成任何傷害。可能這是 SQL Server 功能尚未涵蓋的非常具體的案例。
聚集索引的主要特點是數據都是按順序排列的。這允許 SQL “預讀”。因此,例如,如果您在 Date 列上創建 CI 並執行查詢以提取一周或一個月的摘要資訊,那麼 SQL 可以更快地提取數據。
另一方面,如果您必須進行搜尋(例如單個 ID),那麼 CI 與覆蓋 NCI 沒有什麼不同。注意那
covering
部分。這是您可以嘗試的。將您的 CI 放在
Date, OrderId
組合上。這樣做是因為您更有可能在日期上提取範圍數據而不是 Id。還因為您說 80% 的查詢使用日期。其中的某些部分可能也會使用 OrderId。
INCLUDE
然後查看僅使用 OrderId 的查詢使用哪些列,並使用該子句將這些列添加到 OrderId NCI 。如果答案是“他們正在使用這些查詢中的所有列”,只是為了節省時間,那麼 a)您需要查看這些查詢,看看他們是否真的需要所有這些數據,並且 b)是的,您可以INCLUDE
使用所有列在表中。我意識到那將是一個巨大的
INCLUDE
。事實上,它會使你的表的大小翻倍,你需要仔細測試你不會對寫操作產生嚴重的負面影響。但是對於讀取它應該可以正常工作。
一張表只能有一個聚集索引。
有可能重複日期,所以我會將 ID 設為集群 PK。您將獲得有效的聯接。
您不需要告訴 SQL 日期將按順序排列。但這將有助於減少碎片化。只需在 Date 上嘗試一個單獨的非聚集索引。不確定包括 ID 是否會在這裡受益。
查看執行計劃並從那裡進行調整。