我在我的 SQL Server 2014 数据库系统上使用 TPC-H (SF 10)。为了提高查询性能,我决定按日期列对两个最大的表(Lineitem 和 Orders)进行分区(同一磁盘),因为其中许多查询都使用日期范围。首先我决定使用每周分区方案,然后我使用每月方案。我在每个表上都使用了一个聚集列存储索引。我执行了第一个 TPC-H 查询:
SELECT L_RETURNFLAG,
L_LINESTATUS,
SUM(L_QUANTITY) AS SUM_QTY,
SUM(L_EXTENDEDPRICE) AS SUM_BASE_PRICE,
SUM(L_EXTENDEDPRICE*(1-L_DISCOUNT)) AS SUM_DISC_PRICE,
SUM(L_EXTENDEDPRICE*(1-L_DISCOUNT)*(1+L_TAX)) AS SUM_CHARGE,
AVG(L_QUANTITY) AS AVG_QTY,
AVG(L_EXTENDEDPRICE) AS AVG_PRICE,
AVG(L_DISCOUNT) AS AVG_DISC,
COUNT_BIG(*) AS COUNT_ORDER
FROM LINEITEM
WHERE L_SHIPDATE <= dateadd(dd, - 94, cast('1998-12-01'as date))
GROUP BY L_RETURNFLAG,
L_LINESTATUS
ORDER BY L_RETURNFLAG,
L_LINESTATUS;
对于上面的查询,我得到了以下结果。
- 每周分区
- 访问的分区数 348 (1..348)(总共 361 个分区)
- (862194 行未读取,因为它们位于最后一个分区中)
- 逻辑读取:1381
- Lob 逻辑读取:109005
- Lob 物理读取:1371
- Lob 预读读取:200554
- 执行时间:2807 毫秒
- 编译CPU:43
- 编译时间:43
编译内存:1408
每月分区
- 访问的分区数 80 (1..80)(共 84 个分区)
- (881.087 行未读取,因为它们位于最后一个分区中)
- 逻辑读取:2902
- Lob 逻辑读取:617554
- Lob 物理读取:388
- Lob 预读读数:260486
- 执行时间:2680 毫秒
- 编译CPU:12
- 编译时间:12
- 编译内存:872
它们之间最大的区别是使用的批次数量。在每周分区下大约有 333.201 批用于执行索引扫描,而在每月分区下只有 191.275 批。
我对这个结果有点困惑。我预计第一次执行(每周分区)会比第二次更快,因为读取操作更少。每月分区表上的 lob 逻辑读取明显更高,但执行时间、编译 CPU、时间和内存更低。所以我认为每月分区更有效。其他查询的结果看起来几乎相同:(。有人能帮我理解这里发生了什么吗?
所以,我只是用 maxdop 1 再次进行了测试。这是我的结果:
每周分区
- 逻辑读取:1381
- lob 逻辑读取:108619
- lob 物理读取:1362
- lob 预读读取:200664
每月分区
- 逻辑读取:739
- lob 逻辑读取:94901
- lob 物理读取:402
- lob 预读读取:262598
这是执行计划,这两个执行看起来完全一样,这里有一些更详细的信息:
http://i.stack.imgur.com/293oN.png
读操作数的差异没有以前那么大,并且在每周分区下有更多的物理读取。此外,每周分区下还有更多的逻辑读取。这与我的预期完全相反:/。
执行计划,(每月分区)我首先创建了一个 CI,然后创建了一个聚集列存储索引(使用 drop existing = on 和 maxdop 1)