我似乎在对 aSELECT IN
和 a使用硬编码值之间存在巨大的性能差距STRING_SPLIT
。除了最后一个阶段为STRING_SPLIT
代码多次执行索引查找之外,查询计划是相同的。结果是大约 90000 与大约 15000(根据dm_exec_query_stats
)的 CPU 时间,因此差异是巨大的。我已经在这里发布了两个计划......
有趣的是查询计划显示的成本几乎相同,但是当我检查dm_exec_query_stats
成本 ( last_worker_time
)时却大不相同。
这是查询计划的 2 个输出...
0x79DEAD79D1F149CD 16199
select *
from fn_get_samples(1) s
where s.sample_id in
(2495,2496,2497,2498,2499,2500,2501,2502,2503,2504)
0x4A073840486B252C 86689
select *
from fn_get_samples(1) s
where s.sample_id in
(select value as id
from
STRING_SPLIT('2495,2496,2497,2498,2499,2500,2501,2502,2503,2504',','))
Run Code Online (Sandbox Code Playgroud)
功能代码是...
CREATE FUNCTION [dbo].[fn_get_samples]
(
@user_id int
)
RETURNS TABLE
AS
RETURN (
-- get samples
select s.sample_id,language_id,native_language_id,s.source_sentence,s.markup_sentence,s.latin_sentence,
s.translation_source_sentence,s.translation_markup_sentence,s.translation_latin_sentence,
isnull(sample_vkl.knowledge_level_id,1) as vocab_knowledge_level_id,
isnull(sample_gkl.grammar_knowledge_level_id,0) as grammar_knowledge_level_id, …
Run Code Online (Sandbox Code Playgroud) performance sql-server execution-plan string-splitting query-performance
我清除了我的统计数据并运行了我的查询。实际执行计划的总估计成本为 0.61。我使用dmv 中的total_worker_time
列dm_exec_query_stats
来计算平均 20858 微秒的 CPU 时间:
(SUM(query_stats.total_worker_time) / SUM(query_stats.execution_count))
Run Code Online (Sandbox Code Playgroud)
该计划推荐了一个索引,我创建了该索引。我清除了我的统计信息,然后再次运行查询。这一次,该计划在顶层的总估计成本为 0.37。我dm_exec_query_state
再次检查了dmv,现在平均 CPU 时间为 51536 微秒。
我原以为工人的时间大约是一半,而不是两倍!我在这里错过了什么吗?为什么查询计划的改进没有反映在 exec 查询统计信息中?两个计划在这里上传: