事件
3月31日 下午11時 - 4月2日 下午11時
最大的 SQL、網狀架構和 Power BI 學習事件。 3 月 31 日 - 4 月 2 日。 使用程式代碼 FABINSIDER 來節省 $400 美元。
立即註冊
適用於:SQL Server
Azure SQL 資料庫
Azure SQL 受控執行個體
所有記憶體最佳化資料表都必須至少有一個索引,因為它是將資料列連線在一起的索引。 在記憶體最佳化資料表上,每個索引也會進行記憶體最佳化。 有數種方式可用來區分經記憶體最佳化的資料表上的索引和以磁碟為基礎之資料表上的傳統索引:
經記憶體最佳化的資料表上的所有索引都會根據資料庫復原期間的索引定義來建立。
索引必須是下列其中一項:
「雜湊」索引會在記憶體最佳化資料表的雜湊索引中詳細討論。
「非叢集」索引會在記憶體最佳化資料表的非叢集索引中詳細討論。
「資料行存放區」索引會在另一篇文章中討論。
記憶體優化資料表的每個 CREATE TABLE 語句中必須包含一個索引,這可以透過明確的 INDEX 指定,或隱含地透過 PRIMARY KEY 或 UNIQUE 條件約束來實現。
記憶體最佳化資料表必須具備主索引鍵,才能以預設的 DURABILITY = SCHEMA_AND_DATA 來宣告。 下列 CREATE TABLE 陳述式中的 PRIMARY KEY NONCLUSTERED 子句符合兩個需求:
提供一個索引,以符合 CREATE TABLE 陳述式中的最低索引需求。
提供 SCHEMA_AND_DATA 子句所需的主索引鍵。
CREATE TABLE SupportEvent
(
SupportEventId int NOT NULL
PRIMARY KEY NONCLUSTERED,
...
)
WITH (
MEMORY_OPTIMIZED = ON,
DURABILITY = SCHEMA_AND_DATA);
注意
SQL Server 2014 (12.x) 和 SQL Server 2016 (13.x) 每個記憶體最佳化資料表或資料表類型有 8 個索引的限制。 從 SQL Server 2017 (14.x) 和 Azure SQL 資料庫開始,不再有特定於經記憶體最佳化的資料表和資料表類型的索引數目限制。
本小節包含 Transact-SQL 程式碼區塊,示範在記憶體最佳化資料表上建立各種索引的語法。 這個程式碼示範下列作業:
建立記憶體最佳化資料表。
使用 ALTER TABLE 陳述式新增兩個索引。
插入 (INSERT) 數個資料列的資料。
DROP TABLE IF EXISTS SupportEvent;
go
CREATE TABLE SupportEvent
(
SupportEventId int not null identity(1,1)
PRIMARY KEY NONCLUSTERED,
StartDateTime datetime2 not null,
CustomerName nvarchar(16) not null,
SupportEngineerName nvarchar(16) null,
Priority int null,
Description nvarchar(64) null
)
WITH (
MEMORY_OPTIMIZED = ON,
DURABILITY = SCHEMA_AND_DATA);
go
--------------------
ALTER TABLE SupportEvent
ADD CONSTRAINT constraintUnique_SDT_CN
UNIQUE NONCLUSTERED (StartDateTime DESC, CustomerName);
go
ALTER TABLE SupportEvent
ADD INDEX idx_hash_SupportEngineerName
HASH (SupportEngineerName) WITH (BUCKET_COUNT = 64); -- Nonunique.
go
--------------------
INSERT INTO SupportEvent
(StartDateTime, CustomerName, SupportEngineerName, Priority, Description)
VALUES
('2016-02-23 13:40:41:123', 'Abby', 'Zeke', 2, 'Display problem.' ),
('2016-02-24 13:40:41:323', 'Ben' , null , 1, 'Cannot find help.' ),
('2016-02-25 13:40:41:523', 'Carl', 'Liz' , 2, 'Button is gray.' ),
('2016-02-26 13:40:41:723', 'Dave', 'Zeke', 2, 'Cannot unhide column.');
go
重複的索引鍵值可能會降低記憶體最佳化資料表效能。 系統周遊大部分索引讀取和寫入作業項目鏈結的重複項目。 當重複項目的鏈結超過 100 個項目時,效能降低可能會變得很明顯。
在雜湊索引的情況下,這個問題更明顯可見。 基於下列情況,雜湊索引會受到較大的影響:
若要減少索引中的重複項目,請嘗試下列調整:
如需雜湊衝突的詳細資訊,請參閱記憶體最佳化資料表的雜湊索引。
以下是如何避免索引中任何效率不彰的範例。
請考慮 Customers
資料表,其在 CustomerId
上具有主索引鍵,並在 CustomerCategoryID
資料行上具有索引。 一般來說,指定的類別中會有許多客戶。 因此,所指定索引鍵內會有許多重複的 CustomerCategoryID 值。
在此情況下,最佳做法是在 (CustomerCategoryID, CustomerId)
上使用非叢集索引。 此索引可用於使用 CustomerCategoryID
相關述詞的查詢,但索引鍵不包含重複項目。 因此,重複的 CustomerCategoryID 值或索引中額外資料行,就不會造成索引維護效率不彰。
下列查詢會顯示範例資料庫 CustomerCategoryID
WideWorldImporters Sales.Customers
的資料表 中,上索引之重複索引鍵值的平均數目。
SELECT AVG(row_count) FROM
(SELECT COUNT(*) AS row_count
FROM Sales.Customers
GROUP BY CustomerCategoryID) a
若要評估您自己的資料表和索引的索引鍵重複項目平均數目,請使用您的資料表名稱取代 Sales.Customers
,並使用索引鍵資料行的清單取代 CustomerCategoryID
。
特定查詢的本質會決定哪個索引類型是最佳選擇。
在現有的應用程式中實作記憶體最佳化資料表時,一般建議是由非叢集索引開始,因為其功能與傳統以磁碟為基礎之資料表上的叢集與非叢集索引之功能更為類似。
在下列情況中,非叢集索引會比雜湊索引更適合︰
ORDER BY
子句。WHERE
子句來測試索引資料行︰WHERE StatusCode != 'Done'
WHERE Quantity >= 100
在下列所有 SELECT 中,非叢集索引會比雜湊索引更適合︰
SELECT CustomerName, Priority, Description
FROM SupportEvent
WHERE StartDateTime > DateAdd(day, -7, GetUtcDate());
SELECT StartDateTime, CustomerName
FROM SupportEvent
ORDER BY StartDateTime DESC; -- ASC would cause a scan.
SELECT CustomerName
FROM SupportEvent
WHERE StartDateTime = '2016-02-26';
雜湊索引主要用於點查閱,而非用於範圍掃描。
當查詢使用等號比較述詞時,雜湊索引會比非叢集索引更合適,且 WHERE
子句會對應至所有索引鍵資料行,如下列範例所示:
SELECT CustomerName
FROM SupportEvent
WHERE SupportEngineerName = 'Liz';
多重資料行索引可能是非叢集索引或雜湊索引。 假設索引資料行是 col1 和 col2。 假設有下列 SELECT
陳述式,則只有非叢集索引會有助於查詢最佳化工具︰
SELECT col1, col3
FROM MyTable_memop
WHERE col1 = 'dn';
雜湊索引需要 WHERE
子句來指定索引鍵中每個資料行的等號比較測試。 否則雜湊索引對查詢最佳化工具沒有助益。
如果 WHERE
子句只指定索引鍵中的第二個資料行,則兩種索引類型皆無用。
下表列出各種索引類型支援的所有運算。 「是」表示索引可以有效率地為要求提供服務,「否」則表示索引無法有效率地滿足要求。
作業 | 記憶體最佳化、 雜湊 |
記憶體最佳化、 非叢集 |
以磁碟為基礎、 (非)叢集 |
---|---|---|---|
索引掃描,擷取所有資料表資料列。 | 是 | 是 | 是 |
等號比較述詞 (=) 的索引搜尋。 | 是 (需要有完整索引鍵。) |
是 | 是 |
不等比較和範圍述詞的索引搜尋 (>, , <<=, >=, BETWEEN 。 |
不 (產生索引掃描。) |
是 1 | 是 |
依照排序次序擷取符合索引定義的資料列。 | 否 | 是 | 是 |
依照排序次序擷取符合相反索引定義的資料列。 | 否 | 否 | 是 |
1 針對經記憶體最佳化的非叢集索引,不需要完整的索引鍵來執行索引搜尋。
利用自適性索引重組等解決方案,為一或多個資料庫自動管理索引重組以及統計資料更新。 這項程序會根據索引分散程度與其他參數,自動選擇要進行重建或是重新組織索引,並以線性閾值更新統計資料。
事件
3月31日 下午11時 - 4月2日 下午11時
最大的 SQL、網狀架構和 Power BI 學習事件。 3 月 31 日 - 4 月 2 日。 使用程式代碼 FABINSIDER 來節省 $400 美元。
立即註冊訓練
模組
使用 Azure Data Studio 在 Azure SQL Database 中設計高效能資料模型 - Training
了解如何建立資料模型、資料表、索引、條件約束,以及搭配 Azure Data Studio 使用資料類型。
認證
Microsoft Certified: Azure Cosmos DB Developer Specialty - Certifications
透過 Microsoft Azure Cosmos DB 在 SQL API 和 SDK 中撰寫有效率的查詢、建立索引編製原則、管理及佈建資源。
文件
SQL Server 及 Azure SQL 索引架構與設計指南 - SQL Server
了解如何在 SQL Server 及 Azure SQL 中設計有效的索引以達到良好的資料庫和應用程式效能。 閱讀索引結構和最佳做法。
索引
針對雜湊索引進行疑難排解 - 記憶體最佳化資料表 - SQL Server
您可使用這項資訊,針對 SQL Server 和 Azure SQL Database 中經記憶體最佳化的資料表雜湊索引進行疑難排解。