我们正在使用分区来减少由于锁定而阻塞我们 OLTP 系统体验的数量,分区方案根据客户 ID 将工作表拆分为 100 个分区。然而,我们在测试过程中发现执行计划的选择方式并不完全符合我们的预期。
测试场景是具有 300,000 条联系人记录的单个客户(每个联系人的数据分布在两个表中),所有记录都位于单个分区中,并通过查询在客户分区中查找 500 条特定行。您会期望像哈希匹配这样的东西来消除不需要的 299,500 以在计划的早期启动,但看起来 SQL Server 选择获取整个表的记录数并在考虑如何之前对所有分区进行平均它将处理许多记录,这导致它选择嵌套循环并在该过程的后期消除不需要的记录。通常,对于非分区表进行相同查询所需的时间是其 9 倍。
奇怪的是,向选择添加一个选项(重新编译)给出了一个明智的计划,但我不知道为什么这会有所作为。这不是存储过程,在测试期间,我们在每次测试运行之前清除过程缓存。
当所涉及的表未分区时,不会看到此行为,即每次选择适当的计划,因为估计的行数与实际数相匹配
对这种行为的任何见解将不胜感激。
架构设置:
USE [Scratch]
GO
CREATE SCHEMA part
GO
CREATE PARTITION FUNCTION [ContactPartition](smallint) AS RANGE LEFT FOR VALUES (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, …Run Code Online (Sandbox Code Playgroud)