调整此查询的性能

Posted

技术标签:

【中文标题】调整此查询的性能【英文标题】:Performance tuning this query 【发布时间】:2020-11-06 19:22:30 【问题描述】:

我有以下(简单)查询,大约需要 22 秒才能完成:

SELECT 
    c.city_name, c.task_name, COUNT(c.customer_id) AS customers, 
    ROUND(SUM(c.opportunitySize),2) AS opportunitySize
FROM
    customeropp AS c
WHERE 
    account_id = '1000' AND campaign_cycle = 'm07a2020'
GROUP BY 
    c.city_name, c.task_name    
ORDER BY 
    opportunitySize DESC        
FOR JSON PATH

我的理解是索引可以提高速度所以我也添加了以下索引

CREATE NONCLUSTERED INDEX IX_campaign_and_account 
    ON customeropp (campaign_cycle, account_id) WITH (DROP_EXISTING = ON);

CREATE NONCLUSTERED INDEX IX_city_name 
    ON customeropp (city_name) WITH (DROP_EXISTING = ON);

CREATE NONCLUSTERED INDEX IX_task_name 
    ON customeropp (task_name)  WITH (DROP_EXISTING = ON);

CREATE NONCLUSTERED INDEX IX_opportunitySize 
    ON customeropp (opportunitySize DESC)  WITH (DROP_EXISTING = ON);

还有一些其他索引,但与此特定查询无关。

列类型如下:

目前使用的表大约有 300 万条记录,数据库在无服务器 Azure 数据库计划中运行(最多 40 个 vCore,最多 120 GB 内存)。

知道如何让这个运行得更快吗?

编辑:

执行计划见:https://www.brentozar.com/pastetheplan/?id=SkSt_mQKv

【问题讨论】:

能否请您将实际执行计划发布到brentozar.com/pastetheplan 执行计划是什么?查询简单 - 将结果转换为 JSON 的成本很高。按 聚合 排序需要在排序之前计算和假脱机 tempdb 中的所有结果,这意味着没有任何索引可以用于加速排序操作 获取实际执行计划解释here。您可以在( account_id, campaign_cycle, city_name, task_name ) include ( customer_id, opportunitySize ) 上尝试covering index。它按顺序处理wheregroup by 子句,并提供selectorder by 子句所需的剩余数据。 @HABO 哇...随着您涵盖索引建议,查询现在不到 1 秒。感觉就像魔术! 【参考方案1】:

在索引定义中使用包含列

CREATE  INDEX index_name
ON table_name(campaign_cycle, account_id)
INCLUDE(city_name, task_name, opportunitySize,  customer_id );

【讨论】:

这个似乎提高了查询性能,但不如上面的@HABO建议 最好选择的列在包含的列中 @Mrsmiri 该索引主要提高where 子句(account_idcampaign_cycle)的性能,但它也可以通过以下方式提高group by ( city_name` 和task_name)的性能对这些列进行排序。此时,唯一不在索引中的select 列是customer_idopportunitySize。可以从表行中检索它们,但使用include 将它们添加到索引允许执行查询而根本不访问表行。理论上,至少。也许@JavierC 会将新的执行计划添加到帖子中,以便我们查看。 @HABO 这是新的执行计划brentozar.com/pastetheplan/?id=Byhv6IEFD

以上是关于调整此查询的性能的主要内容,如果未能解决你的问题,请参考以下文章

针对 DELETE 查询的 MySQL 性能调整

如何对此查询进行性能调整

性能调整实体框架查询

如何对Oracle sql 进行性能优化的调整

在 Snowflake 中,调整现有仓库的大小是不是有助于提高正在运行的查询的性能?

MySQL关于财政年度的查询性能调整