查询在 Azure 中执行缓慢的瓶颈是什么

What is bottleneck for query to perform slow in Azure

我在标准层有 Azure SQL 数据库,10 DTU

我如何在 CPU 密集查询中 "predict" 性能(因为这似乎是缓慢的原因)?

为了说明问题将使用 perf_test table,可以像这样填充(脚本可以改进很多,但这不是重点):

CREATE TABLE dbo.perf_Test
(
    PolicyDescriptionID INT IDENTITY PRIMARY KEY,
    col1 NVARCHAR(100),
    col2 NVARCHAR(100),
    col3 NVARCHAR(100),
    col4 NVARCHAR(100),
    col5 NVARCHAR(100),
)

GO
SET NOCOUNT ON; 

DECLARE @i INT = 0
WHILE @i < 100000
BEGIN 
    DECLARE @NumberI int = CAST(RAND() * 100000 AS INT);
    DECLARE @NumberC VARCHAR(6);
    SET @NumberC = 
        CASE
            WHEN @NumberI < 10 THEN '00000' + CAST(@NumberI AS VARCHAR(6))
            WHEN @NumberI < 100 THEN '0000' + CAST(@NumberI AS VARCHAR(6))
            WHEN @NumberI < 1000 THEN '000' + CAST(@NumberI AS VARCHAR(6))
            WHEN @NumberI < 10000 THEN '00' + CAST(@NumberI AS VARCHAR(6))
            WHEN @NumberI < 100000 THEN '0' + CAST(@NumberI AS VARCHAR(6))
            ELSE CAST(@NumberI AS VARCHAR(6))
        END;

    INSERT INTO dbo.perf_Test(col1, col2, col3, col4, col5)
            VALUES(
                @NumberC, -- char
                @NumberC + RIGHT(@NumberC, 3) + @NumberC, -- casts as nvarchar
                @NumberC + 'adslk3ājdsfšadjfads',
                @NumberC, 
                @NumberC
                );
    SET @i = @i + 1;
END

对于许多查询,Azure 将执行与本地计算机相同的操作。但是对于 丑陋的 查询,它的性能要差得多:

SELECT * 
FROM dbo.perf_Test
WHERE 
       col1 LIKE '%263a%'
    OR col2 LIKE '%263a%'
    OR col3 LIKE '%263a%'
    OR col4 LIKE '%263a%'
    OR col5 LIKE '%263a%'

蔚蓝: 扫描计数 1,逻辑读取 1932(其余 0) SQL 服务器执行时间:CPU time = 16 ms,elapsed time = 6718 ms

本地: 扫描计数 1,逻辑读取 1932 SQL 服务器执行时间:CPU time = 563 ms,elapsed time = 482 ms.

逻辑读取与 'bad' 示例相同,但此查询在 azure 中执行大致相同:

SELECT * 
FROM dbo.perf_Test
WHERE col2 = '038743743038743'

蔚蓝: 扫描计数 1,逻辑读取 1932 SQL 服务器执行时间:CPU 时间 = 32 毫秒,经过时间 = 22 毫秒。

本地: 扫描计数 1,逻辑读取 1932 SQL 服务器执行时间:CPU 时间 = 16 毫秒,运行时间 = 7 毫秒。

返回的行约为 100 行 - 与 'bad' 示例相同,但此查询在 azure

中的执行大致相同
SELECT * 
FROM dbo.perf_Test
WHERE col1 like N'0975%'

蔚蓝: 扫描计数 1,逻辑读取 1932 SQL 服务器执行时间:CPU 时间 = 16 毫秒,经过时间 = 26 毫秒。

本地: 扫描计数 1,逻辑读取 1932 SQL 服务器执行时间:CPU 时间 = 15 毫秒,经过时间 = 35 毫秒。

如果我进行一些 CPU 密集查询,差异又是巨大的(2 vs 35 秒,天蓝色):

SELECT SUM(CAST(t1.col1 AS BIGINT) + CAST(t2.col1 AS BIGINT)), COUNT(t2.col1)
FROM dbo.perf_Test t1
    CROSS JOIN dbo.perf_Test t2
WHERE t1.col3 LIKE '%263a%'
OPTION (MAXDOP 1)

If i put some CPU intensive query, difference again is huge (2 vs 35 seconds in azure):

这是因为在资源可用之前可以限制查询,并且您正在将本地部署与 SQLAZURE(标准第 10 层 DTU)进行比较,这是不准确的比较

下图显示了服务层级的一些粗略读取和写入

您可以假设,标准层测量会少得多,并且当资源不可用于查询时,它将等待。

使用 Azure 时有一些好处,例如透明修补、备份、高可用性,您始终使用企业..所以当您进入云时必须做出一些权衡

以下是我将按顺序尝试的步骤

1.Run 下面查询是否有任何 DTU 指标在一段时间内始终 >90%,如果是,我会升级到下一个服务层级

select   top 1 with ties end_time,B.DTUpcnt,b.DTUMetric
 from sys.dm_db_resource_stats t
 cross apply
(values
     (avg_cpu_percent,'avg_cpu_percent'),
     (avg_data_io_percent,'avg_data_io_percent'),
     (avg_memory_usage_percent,'avg_memory_usage_percent'),
     (avg_log_write_percent,'avg_log_write_percent')
     )b(DTUPcnt,DTUMetric)
     order by row_number() over (partition by end_time order by DTUMetric desc)

2.I 也会尝试微调使用更多 DTU 或提供更多计算能力的查询

预测交叉连接查询的性能,您需要确保这些表在缓冲区中,因此不会有 IO,这反过来会减少 CPU 使用..

您还可以尝试在 Azure 中使用内存中的 oltp 表来获取关键表