【问题标题】:sql server partition performancesql server 分区性能
【发布时间】:2020-02-21 18:46:19
【问题描述】:

在我们的 SQL Server 数据库中,我们有一个按日期列分区的表。 对于每个日期,我们插入了 50 万条记录。我们注意到查询性能很好 更接近分区开始范围的日期,并且随着每个日期的前进逐渐降级。

这是我的分区函数

CREATE PARTITION FUNCTION partition_position_monthly (DATE)
AS RANGE RIGHT FOR VALUES ('2019-09-01', '2019-11-01');

表格

CREATE TABLE PartitionTest(
    ID int IDENTITY(1,1) NOT NULL,
    col1 varchar(256) ,
    col2 varchar(128) ,
    col3 varchar(128) ,
    BusinessDate date , -- partition column
) ON partition_scheme_monthly(BusinessDate)

BusinessDate 列上有一个聚集索引。

这是使用的查询

select top 1000 * from PartitionTest where BusinessDate = ?

每个营业日期的 CPU 和 IO 记录

营业日期 = 2019-09-01 CPU 时间 = 31 毫秒 扫描计数 1,逻辑读取 80,物理读取 0,,预读读取 0

营业日期 = 2019-09-02 CPU 时间 = 63 毫秒 扫描计数 1,逻辑读取 24905,物理读取 0,预读读取 3131

营业日期 = 2019-09-03 CPU 时间 = 125 毫秒 扫描计数 1,逻辑读取 49727,物理读取 0,预读读取 7

营业日期 = 2019-09-04 CPU 时间 = 172 毫秒 扫描计数 1,逻辑读取 74551,物理读取 0,预读读取 7

营业日期 = 2019-09-05 CPU 时间 = 234 毫秒 扫描计数 1,逻辑读取 99376,物理读取 0,预读读取 117

如您所见,BusinessDates 的 CPU 时间和逻辑读取数逐渐增加 离分区起始范围较远。

这是从分区获取数据时的预期行为吗?

我们计划对月度数据进行分区,接近月底的日子的查询响应时间超出了我们可接受的限制。有没有办法在分区中实现恒定的 CPU 时间和每天的逻辑读取?

PasteThePlan Link

【问题讨论】:

  • 分区是一种数据管理功能,而不是性能功能。如果查询必须搜索多个分区,性能会下降。在这种情况下,您是否真的试图一次读取 500K 行?这是否意味着一个月包含 1500 万行?由于选择性如此低,BusinessDate 索引不是很有用
  • 此测试一次只读取给定日期的前 1000 行。我们的查询总是获取单个业务日期的数据,因此我们不会跨分区搜索数据。奇怪的是逻辑读取的数量在接下来的每一天都在不断增加。 sql server 没有随机访问工具来读取分区内日期的数据。为什么一定要从文件开头依次开始?
  • 前 1000 名是按什么顺序排列的?如果只使用BusinessDate 作为聚集键,则表示其余行是随机排列的。每个日期有 500K 行,服务器很可能决定使用并行执行计划 - 顺便说一句,您没有发布执行计划。在任何情况下,逻辑读取都是logical——它们读取的是缓存,而不是文件。就好像根本没有使用 BusinessDate 索引 - 或者服务器决定,因为它必须查找 1/60 的数据,所以进行扫描比查找要快
  • 上传你的实际计划到brentozar.com/pastetheplan
  • 请发布执行计划。我敢打赌,糟糕的选择性select * 和数据大小会导致并行化表扫描,因为索引不包含所有字段,因此使用它会更昂贵。这将在执行计划中显而易见。如果聚集索引是 ID 并为 Date 加上一个额外的索引,那可能会更好。您还可以使用聚集列存储索引,它本质上是索引压缩整个表。

标签: sql-server database-performance database-partitioning


【解决方案1】:

是的,这是意料之中的。

要在所有日期获得相同/可预测的性能,您要么需要具有前导列 BusinessDate 的索引,要么将分区函数更改为更精细(每天而不是每月)

如果没有这个,它所能做的最好的事情就是为日期找到正确的分区并扫描所有行,直到找到与日期谓词匹配的 1000 行。在您的执行计划中,它以聚集索引键顺序读取分区内的行,并且需要先读取2,001,000,然后才能找到与BusinessDate='2019-10-27' 上的谓词匹配的前一千个。

如果您发现较晚的日期很可能与您的聚集索引键相关(即按聚集索引键排序的行也往往具有较晚的日期)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-14
    • 1970-01-01
    • 2020-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多