在 Azure Synapse Dedicated SQL Pool中優化 SQL 執行涉及了解底層體系結構(例如分布和分區)、查詢優化(例如避免不必要的子查詢和聯接),以及利用具體化視圖和 PolyBase 等工具進行高效數據加載。
1.有效使用分布和分區
Azure Synapse Dedicated SQL Pool使用分布方法將數據分布到多個分布區。選擇正確的分布方法可以顯著提高查詢性能。
最佳實踐:
- 哈希分布:非常適合經常與同一鍵上的其他大型表聯接的表。它確保以最大程度地減少數據移動的方式將數據分布在各個分配中。
- Round-robin分布:適用于沒有明確 join key 的大表。但是,如果涉及聯接,則可能會導致查詢性能低下。
- Replicated表:經常與大型事實表聯接的小維度表可以復制到每個分配,以避免數據移動。
例:
假設您有兩個表:“Orders”(大型事實數據表)和 ‘Customers’(小型維度表)。
- 對 “Customers” 表使用 replicated distribution,因為它很小并且經常在聯接中使用。
- 對 ‘CustomerID’ 等列上的 ‘Orders’ 表使用 哈希分配 以確保聯接期間的最佳性能。
CREATE TABLE Customers
(CustomerID INT,CustomerName VARCHAR(255),...
)
WITH (DISTRIBUTION = REPLICATE);CREATE TABLE Orders
(OrderID INT,CustomerID INT,OrderDate DATETIME,...
)
WITH (DISTRIBUTION = HASH(CustomerID));
2.利用聚集列存儲索引
聚集列存儲索引 (CCI) 針對大型數據掃描和聚合進行了優化。它們以壓縮的列式格式存儲數據,從而顯著減少存儲并提高分析工作負載的查詢性能。
最佳實踐:
- 始終對大型事實表使用 聚集列存儲索引 (CCI),尤其是那些具有數百萬行的事實表。
- 避免在大型表上使用傳統的行存儲索引,因為 CCI 為分析查詢提供了更好的性能。
例:
CREATE TABLE Sales
(SaleID INT,ProductID INT,Date DATE,Amount DECIMAL(18, 2)
)
WITH (CLUSTERED COLUMNSTORE INDEX);
3.最大限度地減少數據移動
分配之間的數據移動 (shuffleling) 會嚴重影響查詢性能。要最大程度地減少數據移動,請執行以下操作:
- 使用正確的聯接鍵:確保聯接中使用的列分布在同一列上或被復制。
- 提前篩選:在查詢中盡早應用篩選條件,以減少正在處理的數據量。
例:
如果您要聯接兩個大型表(“Sales”和“Products”),請確保兩個表都分布在同一個鍵(“ProductID”)上,以避免數據移動。
CREATE TABLE Sales
(SaleID INT,ProductID INT,Date DATE,Amount DECIMAL(18, 2)
)
WITH (DISTRIBUTION = HASH(ProductID));CREATE TABLE Products
(ProductID INT,ProductName VARCHAR(255),Category VARCHAR(255)
)
WITH (DISTRIBUTION = HASH(ProductID));SELECT s.SaleID, p.ProductName, s.Amount
FROM Sales s
INNER JOIN Products p ON s.ProductID = p.ProductID;
4.優化查詢設計
高效的 SQL 查詢設計在性能優化中起著至關重要的作用。
- 避免 SELECT :*始終在 SELECT 子句中指定所需的列,以減少不必要的數據檢索。
- 提前篩選:應用 ‘WHERE’ 子句以最小化數據集大小。
- 避免不必要的子查詢:盡可能使用聯接而不是子查詢,以防止額外的處理。
- 高效使用窗口函數:‘ROW_NUMBER()’、‘RANK()’ 和 ‘SUM()’ 等窗口函數有時可以替換復雜的子查詢或聚合。
例:
而不是:
SELECT * FROM Sales WHERE Amount > 1000;
用:
SELECT SaleID, Amount FROM Sales WHERE Amount > 1000;
5.對大型表進行分區
分區允許您將大型表劃分為更小、更易于管理的部分,從而提高查詢性能,尤其是對于范圍查詢(例如,日期)。
最佳實踐:
- 在常用的篩選條件列(例如日期列)(例如,‘OrderDate’)上對表進行分區。
- 避免過多的分區;分區過多會導致開銷。
例:
CREATE TABLE Sales
(SaleID INT,ProductID INT,SaleDate DATE,Amount DECIMAL(18, 2)
)
WITH (PARTITION (SaleDate));
6.使用物化視圖
具體化視圖存儲復雜查詢的預計算結果,并允許更快地檢索,尤其是對于聚合密集型或聯接密集型查詢。
最佳實踐:
- 將具體化視圖用于復雜的讀取密集型查詢,例如聚合的銷售數據。
- 確保根據業務需求定期刷新物化視圖。
例:
CREATE MATERIALIZED VIEW mv_AggSales AS
SELECT ProductID, SUM(Amount) AS TotalSales
FROM Sales
GROUP BY ProductID;
7.資源類和查詢優先級
Resource classes 控制分配給查詢的資源量 (內存、CPU 等)。為需要更多資源的查詢分配更高的資源類。
最佳實踐:
- 使用 small resource classes(例如,‘smallrc’)進行輕量級查詢。
- 將 大型資源類(例如,‘largerc’)用于資源密集型查詢,如大型聚合。
例:
-- Assign a higher resource class for heavy queries
SET USER = 'username'; -- Implicitly assigned resource class based on user
EXEC sp_set_session_context 'resource_class', 'largerc';
8.使用 Query Performance Insights 監控和優化性能
利用 Azure Synapse Studio 中的“查詢性能見解”來識別資源瓶頸并分析執行計劃。查找:
- 高 CPU 使用率:可能表示缺少索引或查詢優化不佳。
- 高 I/O:可能表明您正在不必要地掃描大量數據。
- Large memory grants:表示資源密集型查詢。
例:
執行查詢后,使用 Query Performance Insight 控制面板查看執行計劃并識別慢速操作(例如,哈希聯接、表掃描)。
9.使用 PolyBase 優化數據加載
從外部源(例如 Azure Blob 存儲)加載大型數據集時,請使用 PolyBase 將數據高效加載到 Synapse SQL 池中。
最佳實踐:
- 使用 PolyBase 將數據從 Azure Data Lake 或 Blob Storage 等外部源加載到 SQL 池中。
- 在加載源數據之前,對源數據進行適當的分區。
例:
CREATE EXTERNAL DATA SOURCE MyBlobStorage
WITH (TYPE = HADOOP, LOCATION = 'abfs://mycontainer@myaccount.dfs.core.windows.net/');CREATE EXTERNAL FILE FORMAT TextFileFormat
WITH (FORMAT_TYPE = DELIMITEDTEXT, FIELD_TERMINATOR = ',', STRING_DELIMITER = '"');CREATE EXTERNAL TABLE ExternalSales
(SaleID INT,ProductID INT,SaleDate DATE,Amount DECIMAL(18, 2)
)
WITH (DATA_SOURCE = MyBlobStorage, FILE_FORMAT = TextFileFormat);INSERT INTO Sales
SELECT * FROM ExternalSales;
10.針對數據傾斜進行優化
當數據在分布區之間分布不均勻時,就會發生數據傾斜,這可能會導致查詢處理不均勻,從而導致性能下降。識別和解決數據傾斜對于高效執行查詢至關重要。
最佳實踐:
- 監控數據分布:確保數據分配不會導致某些分配過載,而其他分配仍未得到充分利用。這可以通過 ‘sys.dm_pdw_nodes’ 視圖的 distribution 列來識別。
- 避免高度偏斜的數據:應謹慎處理具有高度偏斜數據的列(例如,具有很少不同值的日期,如“January 1st”)。對于此類列,請考慮對查找表使用 replicated table 或調整分配鍵。
- 在大型表上使用哈希分布:使用具有高基數且分布均勻的列(例如,‘OrderID’、‘ProductID’)來分布大型表。
示例:
假設您正在處理銷售數據,并且 ‘Region’ 列具有偏態分布(例如,90% 的數據僅來自一個區域)。在這種情況下:
- 您可以避免在 ‘Region’ 上進行 哈希分配。
- 復制小表(如 ‘Regions’ )進行查找。
-- Sales table with hash distribution on a more evenly distributed column
CREATE TABLE Sales
(SaleID INT,RegionID INT,SaleDate DATE,Amount DECIMAL(18, 2)
)
WITH (DISTRIBUTION = HASH(SaleID));-- Regions table with replication to avoid skew in joins
CREATE TABLE Regions
(RegionID INT,RegionName VARCHAR(255)
)
WITH (DISTRIBUTION = REPLICATE);
11.最小化跨數據分布聯接
當聯接所需的數據駐留在不同的分配上時,就會發生跨分配聯接,這可能會導致 數據移動 和性能問題。這種情況經常發生在非鍵聯接或表未分布在同一列上時。
最佳實踐:
- 在分布式列上聯接:始終嘗試聯接在同一鍵(例如,‘CustomerID’、‘ProductID’)上分布的表。
- 廣播小型表:對于較小的維度表,請使用 復制 以避免在聯接期間移動數據。
示例:
假設您有兩個表:“Orders”(大)和 “Customers”(小)。在 ‘CustomerID’ 上分配 ‘Orders’ 并復制 ‘Customers’ 以實現高效聯接。
-- Replicated Customers table to avoid data movement
CREATE TABLE Customers
(CustomerID INT,CustomerName VARCHAR(255),...
)
WITH (DISTRIBUTION = REPLICATE);-- Orders table distributed by CustomerID for efficient join
CREATE TABLE Orders
(OrderID INT,CustomerID INT,OrderDate DATE,Amount DECIMAL(18, 2)
)
WITH (DISTRIBUTION = HASH(CustomerID));
12.避免在查詢中使用標量函數
標量函數會顯著降低性能,尤其是在大型數據集中,因為它們可能會逐行執行。相反,請盡可能使用 inline expressions 或 joins。
最佳實踐:
- 避免在 ‘SELECT’ 或 ‘WHERE’ 子句中使用 標量函數,尤其是對于大型數據集。
- 考慮使用 內聯 ‘CASE’ 語句 或 joins 作為標量函數的替代方案。
示例:
不要使用標量函數來計算折扣,而是直接在 ‘SELECT’ 語句中執行。
不良做法:
SELECT OrderID, CustomerID, dbo.fn_calculate_discount(Amount) AS Discount
FROM Orders;
最佳實踐:
SELECT OrderID, CustomerID, Amount * 0.10 AS Discount
FROM Orders;
13.使用資源類的查詢并行性
Azure Synapse SQL 池使用 資源類 來控制查詢并行度和資源。通過調整資源類,您可以控制查詢獲取的資源數量,從而提高性能。
最佳實踐:
- 為復雜的查詢或操作設置適當的資源類。較大的資源類將為查詢分配更多的內存和 CPU。
- 為不同的工作負載使用正確的資源類:
- ‘smallrc’:用于小型查詢。
- ‘mediumrc’:用于中間工作負載。
- ‘largerc’:用于繁重的聚合和數據處理查詢。
示例:
如果要對大型數據集運行繁重的聚合查詢,則可能需要使用更大的資源類。
-- Assign the session to a larger resource class
SET RESOURCE_CLASS = 'largerc';-- Complex aggregation query
SELECT ProductID, SUM(Amount) AS TotalAmount
FROM Sales
GROUP BY ProductID;
14.使用 Query Store 分析和優化查詢
Azure Synapse 具有 查詢存儲 功能,可提供歷史查詢性能指標,這有助于識別一段時間內的低效查詢。
最佳實踐:
- 啟用查詢存儲:監控一段時間內的查詢性能,并識別可能導致性能問題的查詢。
- 分析執行計劃:使用 Query Store 分析運行緩慢的查詢的執行計劃,并找到優化它們的方法(例如,索引、查詢重寫)。
示例:
啟用并使用 Query Store 來分析歷史查詢:
-- Enable Query Store
ALTER DATABASE [YourDatabase] SET QUERY_STORE = ON;-- Query performance analysis via Query Store views
SELECT *
FROM sys.query_store_runtime_stats
ORDER BY execution_count DESC;
15.優化聚合和分組依據
聚合操作可能占用大量資源。高效處理聚合,尤其是在大型數據集上,對于實現最佳性能至關重要。
最佳實踐:
- 有效使用 ‘GROUP BY’:除非絕對必要,否則盡量避免對大列進行分組。
- 如果從大型非關鍵數據集讀取數據,請在聚合查詢上使用 ‘WITH (NOLOCK)’。這可以減少阻塞。
- 使用索引視圖 或 具體化視圖 來存儲預先計算的聚合結果。
示例:
使用索引視圖或具體化視圖來存儲預先聚合的數據可以提高報表查詢的性能。
CREATE MATERIALIZED VIEW mv_ProductSales AS
SELECT ProductID, SUM(Amount) AS TotalSales
FROM Sales
GROUP BY ProductID;
現在,您可以查詢具體化視圖,而不是直接查詢 ‘Sales’:
SELECT ProductID, TotalSales
FROM mv_ProductSales;
16.Leverage Result Caching
Azure Synapse SQL 池支持結果緩存,它緩存頻繁執行的查詢的結果。重新運行相同的查詢可以從緩存中檢索結果,而不是重新執行查詢。
最佳實踐:
- 利用結果緩存:如果您經常運行相同的查詢(例如,在控制面板或報告中),結果緩存可以顯著加快執行速度。
- 監控緩存命中/未命中率:您的查詢與現有緩存結果的匹配度越高,您的性能就越好。
示例:
若要強制 Azure Synapse 在重大更改(例如表更新)后清除緩存,可以使用以下內容:
-- Clear the cache for a specific table
DROP TABLE IF EXISTS Sales;
如果啟用了緩存,則可以減少重復查詢的時間。
17.優化數據類型
使用適當的數據類型可以最大限度地減少 I/O 操作并減少類型轉換的需求,從而大大減少存儲占用量并提高查詢性能。
最佳實踐:
- 選擇合適的數據類型:避免使用不必要的大數據類型。例如,如果值在 ‘INT’ 范圍內,則使用 ‘INT’ 而不是 ‘BIGINT’。
- 在適當的情況下,對可變長度字符串字段使用 ‘VARCHAR(n)’ 而不是 ‘TEXT’。
- **僅在需要時使用 ‘DECIMAL’ 或 ‘NUMERIC’ 對于定點數;使用 ‘FLOAT’ 或 ‘REAL’ 進行近似值。
示例:
選擇更合適的數據類型:
-- Instead of using VARCHAR(MAX), limit the size to save space
CREATE TABLE Products
(ProductID INT,ProductName VARCHAR(100), -- More efficient sizePrice DECIMAL(10, 2)
);
18.謹慎使用表值函數 (TVF)
雖然表值函數 (TVF) 提供了可重用的邏輯,但它們通常會由于逐行執行而降低性能,尤其是在聯接或聚合中使用時。
最佳實踐:
- 避免在復雜查詢中使用 TVF:當性能受到關注時,請考慮將 TVF 替換為 內聯查詢 或 CTEs(公用表表達式)。
- 使用內聯表值函數 (iTVF):這些函數比多語句 TVF 更高效,因為它們由查詢計劃程序進行優化。
示例:
使用內聯表值函數而不是多語句函數:
-- Inline TVF: More efficient
CREATE FUNCTION dbo.fn_GetProductSales(@ProductID INT)
RETURNS TABLE
AS
RETURN (SELECT SaleID, AmountFROM SalesWHERE ProductID = @ProductID
);-- Using the inline TVF
SELECT * FROM dbo.fn_GetProductSales(101);
19.使用 ‘MERGE’ 進行高效的更新插入**
對于需要執行 更新插入(insert/update operations) 的場景,‘MERGE’ 語句可能比單獨執行 ‘INSERT’ 和 ’
UPDATE“ 操作。
示例:
MERGE INTO TargetTable AS target
USING SourceTable AS source
ON target.ID = source.ID
WHEN MATCHED THENUPDATE SET target.Value = source.Value
WHEN NOT MATCHED BY TARGET THENINSERT (ID, Value) VALUES (source.ID, source.Value);
20.根據工作負載設置適當的 SQL 池縮放
根據工作負載需求適當擴展 SQL 池對于性能和成本都很重要。
最佳實踐:
- 在高工作負載期間縱向擴展:對于大型 ETL 或復雜查詢,請增加數據分發單元 (DWU) 的數量。
- 在高工作負載后縮減:不運行大型查詢時,縮減資源以降低成本。
示例:
您可以使用以下命令調整 SQL 池的資源:
-- Scale up to DW1000c for intensive queries
ALTER DATABASE [YourDatabase] MODIFY (SERVICE_OBJECTIVE = 'DW1000c');-- Scale down after workload is complete
ALTER DATABASE [YourDatabase] MODIFY (SERVICE_OBJECTIVE = 'DW100c');
21.使用排序數據高效處理大型連接
在執行聯接時,尤其是在大型表上,在聯接之前對數據進行排序有時可以通過減少 shuffle 的需求并提高并行度來優化性能。
最佳實踐:
- 在執行聯接之前對表進行預排序:如果要聯接大型表,則提前按聯接鍵對表進行排序可以減少聯接過程中的數據隨機排序。
- 聚集列存儲索引 (CCI):使用 CCI 時,數據已以排序方式存儲,因此這可能會自然地針對聯接進行優化。
示例:
考慮在 ‘CustomerID’ 上聯接兩個大型表,即 ‘Orders’ 和 ‘Customers’。提前對它們進行排序可以提高性能:
-- Sorting Orders and Customers before joining
CREATE CLUSTERED INDEX idx_orders_customerid
ON Orders (CustomerID);CREATE CLUSTERED INDEX idx_customers_customerid
ON Customers (CustomerID);-- Then perform the join
SELECT o.OrderID, c.CustomerName, o.Amount
FROM Orders o
JOIN Customers c ON o.CustomerID = c.CustomerID;
通過在聯接鍵上創建聚集索引,Synapse 將使用這些排序鍵來最大程度地減少數據隨機排序并改進并行查詢執行。
22.針對資源類中的單節點查詢進行優化
某些查詢可能需要比其他查詢多得多的資源,對于這些類型的查詢,您可以優化它們以在單個節點上運行,而不是使用整個分布式池。
最佳實踐:
- 使用 單節點查詢 卸載不需要分布式處理的大型復雜分析查詢。
- 對無法從并行執行中受益的查詢使用 ‘WITH (QUERY_HINTS = ‘FORCE_SINGLE_NODE’)’。
示例:
如果您正在運行不需要分布式執行的查詢 (e.g.,它只是一個簡單的查找或小的聚合),強制它在單個節點上運行以加快處理速度:
-- Force the query to run on a single node
SELECT CustomerName, SUM(Amount)
FROM Sales
GROUP BY CustomerID
OPTION (QUERY_HINTS = 'FORCE_SINGLE_NODE');
這將減少跨多個節點分發和協調執行的開銷。
23.對基于時間的查詢使用高效的日期處理
基于日期的查詢通常涉及大量數據,尤其是在 Synapse 等分析環境中。有效處理日期列是優化查詢性能的關鍵。
最佳實踐:
- 按日期對表進行分區:如果可能,請按日期對大型表(例如,‘Sales’、‘Transactions’)進行分區,以通過縮小掃描范圍來顯著提高查詢性能。
- 使用適當的日期格式: 對于基于特定日期范圍的查詢,請確保您使用最有效的數據類型(例如,“DATE”與“DATETIME”)。
示例:
按 ‘YearMonth’ 對表進行分區以優化基于日期的查詢的性能:
CREATE TABLE Sales
(SaleID INT,ProductID INT,SaleDate DATE,Amount DECIMAL(18, 2)
)
WITH (PARTITION (YEAR(SaleDate), MONTH(SaleDate)));
查詢特定月份時,Synapse 只能掃描該分區,而不是整個表:
SELECT ProductID, SUM(Amount)
FROM Sales
WHERE SaleDate BETWEEN '2025-01-01' AND '2025-01-31'
GROUP BY ProductID;
24.使用分組集針對聚合查詢進行優化
聚合查詢,尤其是涉及多個 GROUP BY 列或 匯總操作的查詢,可以受益于 分組集 或 CUBE 等高級技術,以減少冗余并提高性能。
最佳實踐:
- 使用 GROUPING SETS 在一次掃描中計算多個聚合,從而減少對數據進行多次傳遞的需要。
- 使用 CUBE 或 ROLLUP 在復雜查詢中進行多級聚合。
示例:
如果您需要同時按 ‘ProductID’ 和 ‘Region’ 以及兩者來計算 ‘SUM(Amount)’,則可以使用 GROUPING SETS 來減少冗余查詢:
SELECT ProductID, Region, SUM(Amount)
FROM Sales
GROUP BY GROUPING SETS((ProductID, Region),(ProductID),(Region),());
此查詢將按“ProductID”和“Region”有效地計算“Amount”的總和,也可以按每個總和單獨計算。
25.使用 Window Functions 優化復雜聚合
窗口函數(如 ‘ROW_NUMBER()’、‘RANK()’ 和 ‘SUM()’ 對于復雜的聚合場景可能非常有用,但使用它們不當(例如,沒有分區)可能會導致查詢效率低下。
最佳實踐:
- 按適當的列分區 以避免全表掃描。
- 在窗口函數中謹慎使用 ‘ORDER BY’ 以避免不必要的排序。
- 使用 ‘OVER()’ 子句來避免多次傳遞數據。
示例:
您可以使用窗口函數在一次傳遞中計算累積總計,而不是運行子查詢來計算累積總計:
SELECT ProductID, SaleDate, Amount,SUM(Amount) OVER (PARTITION BY ProductID ORDER BY SaleDate) AS CumulativeSales
FROM Sales;
在此示例中,計算累積總和,按 ‘ProductID’ 分區,并按 ‘SaleDate’ 排序,無需多次查詢或聯接。
26.使用查詢調控器限制資源消耗
如果 SQL 池在多個用戶或進程之間共享,請務必通過大型查詢來 限制資源消耗 ,以防止它們使系統不堪重負。這可以使用 Query Governor 功能來完成。
最佳實踐:
- 啟用查詢調控器:您可以設置一個查詢調控器限制來限制查詢使用的資源量,確保長時間運行的查詢不會消耗太多資源。
- 設置最大超時:這在意外查詢可能會消耗大量資源的環境中特別有用。
示例:
-- Set query governor to limit execution time (in seconds)
EXEC sp_configure 'query governor', 120; -- Limit to 120 seconds
RECONFIGURE;
這將自動終止運行時間超過指定時間限制的查詢,從而提高資源公平性。
27.對大型事實表進行分區以實現最佳查詢
根據查詢模式(例如,時間范圍或 ID 范圍)對表進行分區可以提高 I/O 性能和 查詢執行時間。
最佳實踐:
- 根據時間對事實數據表(如 sales 或 transactions)進行分區,因為基于日期的查詢在分析工作負載中很常見。
- 對基于時間的數據或其他適當的列使用 范圍分區。
- 使用 ‘DROP PARTITION’ 和 ‘SWITCH PARTITION’ 來有效地管理分區。
示例:
考慮這樣一個場景:您按 year and month** 對 sales 表進行分區:
CREATE TABLE Sales
(SaleID INT,ProductID INT,SaleDate DATE,Amount DECIMAL(18, 2)
)
WITH (PARTITION (YEAR(SaleDate), MONTH(SaleDate)));
要快速管理過去的數據,您可以 切換 較舊的分區或 刪除 不再需要的分區:
-- Dropping an old partition for the year 2023
ALTER TABLE Sales SWITCH PARTITION 202301 TO Sales_Archive;
這使得數據管理高效,無需復雜的刪除。
28.使用列存儲索引實現壓縮和查詢速度
列存儲索引 對于提高查詢速度至關重要,尤其是對于大規模、讀取密集型查詢。這是最適合分析工作負載的索引策略。
最佳實踐:
- 對大型表使用聚集列存儲索引 (CCI),以受益于存儲壓縮和查詢性能改進。
- 將 非聚集列存儲索引 用于較小的事實數據表或其他分析列。
- 對于非常寬的表請謹慎使用,因為它們可能會導致內存和 CPU 資源的使用效率低下。
示例:
-- Using clustered columnstore index for a large fact table
CREATE TABLE Sales
(SaleID INT,ProductID INT,SaleDate DATE,Amount DECIMAL(18, 2)
)
WITH (CLUSTERED COLUMNSTORE INDEX);
此表現在受益于列存儲索引提供的壓縮和優化的查詢執行。
29.針對 PolyBase 和外部數據集成進行優化
如果使用 PolyBase 集成來自外部源(如 Azure Blob 存儲或 Azure Data Lake)的大型數據集,則適當的優化可以顯著減少數據加載時間。
最佳實踐:
- 在 Azure Blob 存儲或數據湖中對外部數據進行分區,并在 Synapse 中相應地對目標表進行分區。
- 如果外部數據文件已采用一致的結構化格式,則對文件格式使用 ‘WITH (NOFORMAT)’。
- 對外部數據利用 文件壓縮(例如 Parquet 或 ORC)來減少 I/O 開銷。
示例:
使用 PolyBase 從分區源加載大型數據集:
CREATE EXTERNAL DATA SOURCE BlobStorage
WITH (TYPE = HADOOP, LOCATION = 'abfs://container@storageaccount.dfs.core.windows.net/');CREATE EXTERNAL FILE FORMAT ParquetFileFormat
WITH (FORMAT_TYPE = PARQUET);CREATE EXTERNAL TABLE SalesExternal
(SaleID INT,ProductID INT,SaleDate DATE,Amount DECIMAL(18, 2)
)
WITH (LOCATION = '/data/sales/', DATA_SOURCE = BlobStorage, FILE_FORMAT = ParquetFileFormat);
30.利用具體化視圖實現更快的查詢性能
具體化視圖以物理方式存儲查詢結果并定期刷新它,從而提高 復雜聚合查詢 或 頻繁的報表查詢 的性能。
最佳實踐:
- 將 具體化視圖 用于涉及大型聚合或聯接的頻繁執行的查詢。
- 確保您為具體化視圖設置適當的 刷新策略 ,以平衡性能和數據新鮮度。
示例:
CREATE MATERIALIZED VIEW mv_ProductSales AS
SELECT ProductID, SUM(Amount) AS TotalSales
FROM Sales
GROUP BY ProductID;
此視圖現在將存儲聚合結果,并且查詢它比每次都從基表重新計算聚合要快得多。