当前位置: 首页 > news >正文

优化 Azure Synapse Dedicated SQL Pool中的 SQL 执行性能的经验方法

在 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% 的数据仅来自一个区域)。在这种情况下:

  1. 您可以避免在 ‘Region’ 上进行 哈希分配
  2. 复制小表(如 ‘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 expressionsjoins

最佳实践:
  • 避免在 ‘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 在一次扫描中计算多个聚合,从而减少对数据进行多次传递的需要。
  • 使用 CUBEROLLUP 在复杂查询中进行多级聚合。
示例:

如果您需要同时按 ‘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;

此视图现在将存储聚合结果,并且查询它比每次都从基表重新计算聚合要快得多。

相关文章:

优化 Azure Synapse Dedicated SQL Pool中的 SQL 执行性能的经验方法

在 Azure Synapse Dedicated SQL Pool中优化 SQL 执行涉及了解底层体系结构(例如分布和分区)、查询优化(例如避免不必要的子查询和联接),以及利用具体化视图和 PolyBase 等工具进行高效数据加载。 1.有效使用分布和分…...

详解英语单词“pro bono”:公益服务的表达(中英双语)

中文版 详解英语单词“pro bono”:公益服务的表达 一、词义解释 “Pro bono” 是一个源自拉丁语的短语,完整表达为 “pro bono publico”,意思是“为了公众利益”(for the public good)。在现代英语中,它…...

16. C语言 字符串详解

本章目录: 前言C 字符串的基础概念字符串的定义字符串的内存表示 常见的字符串操作函数示例代码 深入探讨字符串长度计算strlen 与 sizeof 的区别 字符串操作的注意事项**1. 字符数组的大小**2. 字符数组和字符指针的区别3. 使用安全函数 字符串的遍历与格式化输出**遍历字符串…...

使用Buildroot开始嵌入式Linux系统之旅-3

文章目录 at91bootstrap操作教程修改at91bootstrap具体配置重新编译at91bootstrap U-Boot操作教程修改U-Boot具体配置重新编译U-Boot Linux Kernel操作教程修改Linux Kernel具体配置重新编译Linux Kernel buildroot操作进阶生成图形化软件模块依赖关系查看具体软件模块依赖关系…...

[免费]SpringBoot+Vue新能源汽车充电桩管理系统【论文+源码+SQL脚本】

大家好,我是java1234_小锋老师,看到一个不错的SpringBootVue新能源汽车充电桩管理系统,分享下哈。 项目视频演示 【免费】SpringBootVue新能源汽车充电桩管理系统 Java毕业设计_哔哩哔哩_bilibili 项目介绍 随着信息化时代的到来&#xff0…...

【已解决】【记录】2AI大模型web UI使用tips 本地

docker desktop使用 互动 如果需要发送网页链接,就在链接上加上【#】号 如果要上传文件就点击这个➕号 中文回复 命令它只用中文回复,在右上角打开【对话高级设置】 输入提示词(提示词使用英文会更好) Must reply to the us…...

44.ComboBox的数据绑定 C#例子 WPF例子

固定最简步骤,包括 XAML: 题头里引入命名空间 标题下面引入类 combobox绑定资源属性和选择属性,block则绑定和combobox一样的选择属性 C#: 通知的类,及对应固定的任务 引入字段 引入属性 其中资源是只读的 选…...

物联网之传感器技术

引言 在数字化浪潮席卷全球的今天,物联网(IoT)已成为推动各行各业变革的重要力量。而物联网传感器,作为物联网感知层的核心技术,更是扮演着不可或缺的角色。它们如同人类的五官,能够感知物理世界中的各种信…...

QTreeWidget QTreeWidgetItem

QTreeWidgetItem 是 Qt 框架中用于在 QTreeWidget 中表示树形结构中每个节点的类。它是 QTreeWidget 的一部分,允许您创建和管理层次结构的数据展示。 QTreeWidgetItem 用于表示树形结构中的单个节点。 添加子节点: 可以通过 addChild() 方法向节点添加…...

torch.einsum计算张量的外积

torch.einsum 是一种强大的张量操作工具,可以通过爱因斯坦求和约定(Einstein summation convention)来简洁地表示复杂的张量运算。通过它,我们可以高效地计算矩阵乘法、转置、点积、外积等操作。 以下是关于如何使用 torch.einsum 计算两个四维张量在第三维度上的外积的解…...

PostgreSQL 超级管理员详解

1. 什么是 PostgreSQL 超级管理员 PostgreSQL 超级管理员(superuser)是拥有数据库系统最高权限的用户。他们可以执行任何数据库操作,包括但不限于创建和删除数据库、用户、表空间、模式等。超级管理员权限是 PostgreSQL 中权限的最高级别。 …...

RabbitMQ 工作模式使用案例之(发布订阅模式、路由模式、通配符模式)

Hi~!这里是奋斗的明志,很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~~ 🌱🌱个人主页:奋斗的明志 🌱🌱所属专栏:RabbitMQ 📚本系列文章为个人学…...

【2024年华为OD机试】(C卷,100分)- 机场航班调度程序 (Java JS PythonC/C++)

一、问题描述 题目描述 XX市机场停放了多架飞机,每架飞机都有自己的航班号,如CA3385,CZ6678,SC6508等,航班号的前2个大写字母(或数字)代表航空公司的缩写,后面4个数字代表航班信息…...

Vue.js组件开发-使用地图绘制轨迹

在Vue.js中开发一个组件来展示地图并绘制轨迹,可以使用诸如Leaflet.js、Mapbox GL JS或百度地图等地图库。这些库提供了丰富的API来创建和定制地图,以及绘制路径、标记和其他地图元素。 示例: 1. 安装Leaflet.js 首先,需要安装…...

vue 与 vue-json-viewer 实现 JSON 数据可视化

前言 接口的调试和测试是确保系统稳定性的重要步骤。为了让开发人员和测试人员能够直观地查看接口返回的 JSON 数据,使用合适的工具至关重要。vue-json-viewer 插件为 vue 开发者提供了一个简单而强大的解决方案。本文将详细介绍如何在 vue 项目中使用该插件&#x…...

ubuntu Android : adb logcat 过滤多个log

指定字符串的log,可以用下面的形式,注意加-E和单引号: adb shell " logcat | grep -E strings1|strings2 " 参考:Android : adb logcat 过滤多个log 用adb shell “ logcat | grep -E ‘strings1| strings2 ‘ “ 形…...

kubeneters-循序渐进Cilium网络(三)

文章目录 概要命名空间之间的路由同一节点上的 Pod 到 Pod 路由跨节点的 Pod 间路由总结 概要 在前一篇讨论网络接口的内容中,详细分析了如何识别所有参与 Pod 间路由的接口。同时,以简明的非技术语言阐述了 Cilium 在 Kubernetes 集群中的路由机制。接…...

编译与汇编

本文来自《程序员的自我修养》 编译过程是把预处理完的文件进行一系列词法分析,语法分析,语义分析以及优化后生成相应的汇编文件代码。 现在版本的GCC把预编译和编译两个步骤合并为一个步骤。 gcc -S HelloWorld.c HelloWorld.sint main() {//test/* …...

对MySQL滴MVCC理解(超详细)

学习目标 什么是MVCC?MVCC的核心概念MVCC 的工作原理MVCC 的优势MVCC 的劣势 什么是MySQL中InnoDB下滴快照读和当前读?一、快照读(Snapshot Read)二、当前读(Current Read)三、快照读和当前读的区别四、当前…...

Mac玩Steam游戏秘籍!

Mac玩Steam游戏秘籍! 大家好!最近有不少朋友在用MacBook玩Steam游戏时遇到不支持mac的问题。别担心,我来教你如何用第三方工具Crossover来畅玩这些不支持的游戏,简单又实用! 第一步:下载Crossover 首先&…...

【Oracle APEX开发小技巧12】

有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...

MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用

文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...

Golang——7、包与接口详解

包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...

日常一水C

多态 言简意赅:就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过,当子类和父类的函数名相同时,会隐藏父类的同名函数转而调用子类的同名函数,如果要调用父类的同名函数,那么就需要对父类进行引用&#…...

MySQL的pymysql操作

本章是MySQL的最后一章,MySQL到此完结,下一站Hadoop!!! 这章很简单,完整代码在最后,详细讲解之前python课程里面也有,感兴趣的可以往前找一下 一、查询操作 我们需要打开pycharm …...

【Linux】Linux安装并配置RabbitMQ

目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...

FTXUI::Dom 模块

DOM 模块定义了分层的 FTXUI::Element 树,可用于构建复杂的终端界面,支持响应终端尺寸变化。 namespace ftxui {...// 定义文档 定义布局盒子 Element document vbox({// 设置文本 设置加粗 设置文本颜色text("The window") | bold | color(…...

高保真组件库:开关

一:制作关状态 拖入一个矩形作为关闭的底色:44 x 22,填充灰色CCCCCC,圆角23,边框宽度0,文本为”关“,右对齐,边距2,2,6,2,文本颜色白色FFFFFF。 拖拽一个椭圆,尺寸18 x 18,边框为0。3. 全选转为动态面板状态1命名为”关“。 二:制作开状态 复制关状态并命名为”开…...