Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server sql server分区性能_Sql Server_Database Performance_Database Partitioning - Fatal编程技术网

Sql server sql server分区性能

Sql server sql server分区性能,sql-server,database-performance,database-partitioning,Sql Server,Database Performance,Database Partitioning,在SQL Server数据库中,我们有一个按日期列分区的表。 对于每个日期,我们都插入了50万条记录。我们注意到,查询性能对于 更接近分区开始范围的日期,并且随着时间的推移,它会逐渐降级 这是我的配分函数 CREATE PARTITION FUNCTION partition_position_monthly (DATE) AS RANGE RIGHT FOR VALUES ('2019-09-01', '2019-11-01'); 桌子 BusinessDate列上有一个聚集索引 下面是使用

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

这是我的配分函数

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

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 ms 扫描计数1,逻辑读取49727,物理读取0,预读读取7

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

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

正如您所看到的,对于BusinessDate,CPU时间和逻辑读取逐渐增加 远离分区开始范围的

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

我们计划对每月数据进行分区,并且接近月底的天数的查询响应时间超出了我们可以接受的限制。是否有一种方法可以实现分区中每天的恒定CPU时间和逻辑读取

是的,这是预期的

要获得所有日期的同等/可预测性能,您需要一个带前导列的索引
BusinessDate
,或者将分区函数更改为更细粒度(每日而不是每月)

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


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

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