Sql-Server
哪些索引用於在兩列上將表連接到自身
我正在使用 SQL Server 2016,並嘗試將表連接到自身,但查詢非常慢,這似乎是因為 SQL Server 拒絕使用索引。
如果你原諒這個例子的粗魯,我有一張這樣的桌子……
TABLE [Balances] ( account_id NCHAR(20), balance_date DATE, balance INT, next_balance_date DATE )
…我基本上想做這個查詢:
SELECT [t1].*, [t2].[balance] [next_balance] FROM [Balances] [t1] LEFT JOIN [Balances] [t2] ON [t1].[next_balance_date] = [t2].[balance_date] AND [t1].[account_id] = [t2].[account_id]
問題是,無論我嘗試在此表上放置什麼索引,SQL Server 都堅持進行雜湊匹配。在這個大型數據庫上這很慢。
我目前有以下索引:
NONCLUSTERED INDEX [idx_acc_date] ON [Balances] ([account_id] ASC, [balance_date] ASC) NONCLUSTERED INDEX [idx_acc_nextdate] ON [Balances] ([account_id] ASC, [next_balance_date] ASC)
我應該創建哪些索引來加速這個查詢?
(作為數據的一個小註釋 - 所有 balance_dates 都是在月底,因此 next_balance_date 也是如此。此外,每個 account_id 在每個 balance_date 只有一個條目。)
有 2 個選項:
通過 account_id 創建聚集索引。刪除所有其他索引。
添加新列
Balance_ID INT IDENTITY(1,1)
並在該列上創建聚集索引。僅在一個列上創建另一個非聚集索引account_id
。第二種選擇更可取,因為它更快。您
INT
僅加入 4 個字節。雖然您目前的查詢加入了 40 個字節。這意味著您目前的運營成本要高出 10 倍。另外,問自己幾個問題:
你真的需要將 Account_ID 設為 Unicode 嗎?
您可以將 Account_ID 轉換為 INT 或 BIGINT 嗎?
希望你明白我的意思。
添加:
- 您只在一列上創建聚集索引。從技術上講,您可以多次執行此操作,但主要目標是使其盡可能短。
- 如果您
account_id
在該列上創建了聚集索引,則不需要任何其他索引。- 我可以猜測您的性能有所提高,因為在沒有聚集索引之前,索引非常糟糕,以至於 SQL 決定改為進行全表掃描。
- 建議:閱讀一本關於索引、它們的區別以及它們如何工作的書。