在 Azure Data Studio 和 SSMS 或 s-s-rS 中执行 SQL 查询时的不同行为

Posted

技术标签:

【中文标题】在 Azure Data Studio 和 SSMS 或 s-s-rS 中执行 SQL 查询时的不同行为【英文标题】:Different behavior when executing an SQL query in Azure Data Studio and SSMS or s-s-rS 【发布时间】:2021-09-08 02:53:09 【问题描述】:

我有一个查询,其行为取决于执行它的客户端。 我使用 Azure Data Studio 获得了即时结果(163 行)。 SQL Management Studio、Report Builder、s-s-rS Web Portal 超过 7 分钟。

更好的是,如果我从选择中删除两列或添加 2 个空列,我在 SSMS 中也能获得相同的性能。

SELECT
  mycols,
  (...),
  null,
  null
FROM
(...)

解释计划是一样的,我什么都看不懂。调优顾问没有任何建议。

我认为这与为什么客户端选项有关,唯一不同的是 ARITHMETIC_ABORT_ENABLED 为 FALSE。在 SSMS 中设置为 true 后仍然没有效果。

我使用 SQL Server 2019。

这里是查询:

DECLARE @UserID as VARCHAR(30) = CURRENT_USER 
DECLARE @ProductionCenterSwipCode as VARCHAR(30) = 'AIX'
DECLARE @ResourceName as VARCHAR(30) = NULL
DECLARE @ActivityCode as VARCHAR(30) = 'ALL'
DECLARE @SubactivityCode as VARCHAR(30) = 'ALL'
DECLARE @WorkNatureCode as VARCHAR(30) = 'ALL'
DECLARE @ClientId as INT = -9999
DECLARE @ContractId as INT = -9999
DECLARE @StartDate as DATE= CAST( '2021-04-01' AS DATE)
DECLARE @EndDate as DATE = CAST( '2021-05-30' AS DATE)


SELECT concat(cct.cct_activity_domain_code, ' - ', cct.cct_activity_domain_label) domain_of_activity,
       concat(hrh.hrh_production_center_swip_code, ' - ', hrh.hrh_production_center_name) resource_production_center,
       hrh.hrh_full_name resource,
       dat.dat_date Date_logged,
       tim.tim_number_hours_logged time_logged,
       concat(rng.rng_type_of_work_code, ' - ', rng.rng_type_of_work_label) type_of_work,
       tsk.tsk_code task,
       concat(sta.wat_activity_code , ' - ', sta.wat_activity_label) activity,
       cct.cct_client_reference client_contract,
       cli.cli_name client_name,
       wko.wko_swip_id wo_id,
       wko.wko_client_reference wo_client_reference,
       concat(sta.wat_workorder_type_code, ' - ', sta.wat_workorder_type_label) wo_type,
       wko.wko_current_status_label wo_status,
       rng.rng_label range_element,
       rnh.rnh_current_status_label range_element_status,
       concat(sta.wat_subactivity_code, ' - ', sta.wat_subactivity_label) sub_activity,
       concat(sta.wat_nature_of_work_code, ' - ', sta.wat_nature_of_work_label) work_nature,
       concat(sta.wat_priority_code, ' - ', sta.wat_priority_label) priority,
       concat(sta.wat_complexity_code, ' - ', sta.wat_complexity_label) complexity,
       concat(sta.wat_skill_level_code, ' - ', sta.wat_skill_level_label) skill_level,
       concat(sta.wat_program_code, ' - ', sta.wat_program_label) program,
       concat(sta.wat_perimeter_code, ' - ', sta.wat_perimeter_label) technical_scope,
       concat(sta.wat_customer_production_center_code, ' - ', sta.wat_customer_production_center_label) client_production_center,
       concat(sta.wat_scenario_code, ' - ', sta.wat_scenario_label) production_scenario,
       concat(sta.wat_application_classification_code, ' - ', sta.wat_application_classification_label) application_ranking,
       concat(sta.wat_customer_technical_leader_code, ' - ', sta.wat_customer_technical_leader_label) client_technical_leader,
       wko.wko_current_start_date wo_start_date,
       wko.wko_current_commit_end_date wo_end_date_commitment,
       wko.wko_last_delivery_date wo_last_delivery_date,
       wko.wko_highest_id highest_level_wo_id,
       wko.wko_highest_client_reference highest_level_wo_client_refence,
       wko.wko_batch_reference wo_batch_reference,
       wko.wko_label wo_descriprion
FROM dwh_swip.swip.f_logged_time tim
INNER JOIN dwh_swip.swip.d_human_resource_hstr hrh ON hrh.hrh_id = tim.tim_hrh_id
INNER JOIN dwh_swip.swip.d_range_element rng ON rng.rng_id = tim.tim_rng_id
INNER JOIN dwh_swip.swip.d_date dat ON dat.dat_id = tim.tim_dat_id
INNER JOIN dwh_swip.swip.d_range_element_hstr rnh ON rnh.rnh_id = tim.tim_rnh_id
INNER JOIN dwh_swip.swip.d_task tsk ON tsk.tsk_id = tim.tim_tsk_id
INNER JOIN dwh_swip.swip.d_workorder wko ON wko.wko_id = tim.tim_wko_id
INNER JOIN dwh_swip.swip.d_client_contract cct ON cct.cct_id = tim.tim_cct_id
INNER JOIN dwh_swip.swip.d_client cli ON cli.cli_id = tim.tim_cli_id
INNER JOIN dwh_swip.swip.d_wo_structuring_attributes sta ON sta.wat_id = tim.tim_wat_id
WHERE exists ( SELECT 1
    FROM swip.b_user_perimeter
    WHERE upr_domain_id = (@UserID) AND upr_active_domain_code = cct.cct_activity_domain_code )
AND hrh.hrh_production_center_swip_code IN (@ProductionCenterSwipCode)
AND cct.cct_activity_domain_code IN (N'ADS_TD',N'ADS_VV_ILL',N'AC_TD',N'BI',N'DEF_TD',N'DOM_MG',N'HE_TD',N'INDUSTRY',N'LLA DOM',N'NAV_CU_SUP',N'NAV_ENG',N'NAV_TD',N'non applicable',N'llaxx',N'unknown')
AND (@ResourceName IS NULL or @ResourceName IS NOT NULL AND hrh.hrh_full_name like N'%'+ @ResourceName + N'%')
AND ('ALL' in (@ActivityCode) or 'ALL' NOT IN (@ActivityCode) AND sta.wat_activity_code IN (@ActivityCode))
AND ('ALL' in (@SubactivityCode) or 'ALL' NOT IN (@SubactivityCode) AND sta.wat_subactivity_code IN (@SubactivityCode))
AND ('ALL' in (@WorkNatureCode) or 'ALL' NOT IN (@WorkNatureCode) AND sta.wat_nature_of_work_code IN (@WorkNatureCode))
AND (-9999 in (@ClientId) or -9999 NOT IN (@ClientId) AND tim.tim_cli_id IN (@ClientId))
AND (-9999 in (@ContractId) or -9999 NOT IN (@ContractId) AND tim.tim_cct_id IN (@ContractId))
AND  tim.tim_dat_id >= (YEAR(@StartDate)*10000 + MONTH(@StartDate)*100 + DAY(@StartDate))
AND  tim.tim_dat_id <= (YEAR(@EndDate)*10000 + MONTH(@EndDate)*100 + DAY(@EndDate) )

【问题讨论】:

为了更好的 SQL 性能帮助,您需要包含您的表和索引定义,并通过brentozar.com/pastetheplan分享实际查询计划 SSMS 的实际解释计划在这里。 brentozar.com/pastetheplan/?id=B1xAF-Q2u 看计划,我建议你关注隐式转换:例如cct_activity_domain_codevarchar所以值不应该在它们前面有N,还有一些变量/parameters 是错误的类型。但是这里只有几行,所以不会有太大的不同。不敢相信慢版的查询计划是一样的,也请补充一下。 s-s-rS 会自动生成 SQL 来处理 IN 参数。也许我可以为此做点什么。真正的问题是,我复制粘贴整个查询和参数:azuredata studio 中的 0ms ssms 中的 7 分钟。前面的解释计划是缓慢的。我将添加快速的,但出于某种原因,brentozar 说该计划无效。 那是因为你得到了一个不同的计划,因为当你改变任何东西(甚至是格式)时,查询就会被重新编译。请添加快速计划。 【参考方案1】:

这是一个 SQL Server 错误。来自 Microsoft 支持的答复:

问题:您遇到特定查询的性能问题。在 SSMS 和 s-s-rS,完成所需的时间更长。在 Azure 数据工作室 和 SQL CMD,它运行得更快

修复了当查询在 SQL Server 2019 中对使用 UTF8 的数据库进行半联接后输出 NULL 值时的性能问题。

要解决这个问题,你必须在 SQL 上应用最新的 CU,即 CU11

起初,Microsoft 无法弄清楚这一点,因为当时他们不知道行为会根据 SQL 客户端而改变。 现在他们知道了^^

【讨论】:

以上是关于在 Azure Data Studio 和 SSMS 或 s-s-rS 中执行 SQL 查询时的不同行为的主要内容,如果未能解决你的问题,请参考以下文章

跨平台数据库工具Azure Data Studio

Azure Data Studio 不记住或不保留连接

markdown Azure Data Studio

Azure Data Studio 机器学习 - 无法识别 Python 和 R 包

Azure Data Studio 连接问题

Azure Data Studio - 找不到备份选项