use*_*443 7 sql-server execution-plan partitioning sql-server-2017
我创建了一个分区表(如下所示),并播种了 4.8 亿行 - 每个帐户大约 181 行。
我在添加索引之前运行基线查询。我很惊讶地看到,即使在添加option(recompile). 分区表就是这样吗?在我看来,这更像是现实生活,而不是对谓词的分区列值进行硬编码。
最终,如果我对此有疑问,我将添加索引并在此处发回。在我对这篇文章中给出的答案感到满意之前,我不想继续。
--step 2 (after creating db)
ALTER DATABASE partitionresearch
ADD FILEGROUP January
GO
ALTER DATABASE partitionresearch
ADD FILEGROUP February
GO
ALTER DATABASE partitionresearch
ADD FILEGROUP March
GO
ALTER DATABASE partitionresearch
ADD FILEGROUP April
GO
ALTER DATABASE partitionresearch
ADD FILEGROUP May
GO
ALTER DATABASE partitionresearch
ADD FILEGROUP June
GO
ALTER DATABASE partitionresearch
ADD FILEGROUP July
GO
ALTER DATABASE partitionresearch
ADD FILEGROUP August
GO
ALTER DATABASE partitionresearch
ADD FILEGROUP September
GO
ALTER DATABASE partitionresearch
ADD FILEGROUP October
GO
ALTER DATABASE partitionresearch
ADD FILEGROUP November
GO
ALTER DATABASE partitionresearch
ADD FILEGROUP December
GO
--step 3
-- Table Partitioning in SQL Server
ALTER DATABASE [Partitionresearch]
ADD FILE
(
NAME = [PartJan],
FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL14.mycompany2\MSSQL\DATA\PartJan.ndf',
SIZE = 5080 KB,
MAXSIZE = UNLIMITED,
FILEGROWTH = 2040 KB
) TO FILEGROUP [January]
ALTER DATABASE [Partitionresearch]
ADD FILE
(
NAME = [PartFeb],
FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL14.mycompany2\MSSQL\DATA\PartFeb.ndf',
SIZE = 5080 KB,
MAXSIZE = UNLIMITED,
FILEGROWTH = 2040 KB
) TO FILEGROUP [February]
ALTER DATABASE [Partitionresearch]
ADD FILE
(
NAME = [PartMar],
FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL14.mycompany2\MSSQL\DATA\PartMar.ndf',
SIZE = 5080 KB,
MAXSIZE = UNLIMITED,
FILEGROWTH = 2040 KB
) TO FILEGROUP [March]
ALTER DATABASE [Partitionresearch]
ADD FILE
(
NAME = [PartApr],
FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL14.mycompany2\MSSQL\DATA\PartApr.ndf',
SIZE = 5080 KB,
MAXSIZE = UNLIMITED,
FILEGROWTH = 2040 KB
) TO FILEGROUP [April]
ALTER DATABASE [Partitionresearch]
ADD FILE
(
NAME = [PartMay],
FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL14.mycompany2\MSSQL\DATA\PartMay.ndf',
SIZE = 5080 KB,
MAXSIZE = UNLIMITED,
FILEGROWTH = 2040 KB
) TO FILEGROUP [May]
ALTER DATABASE [Partitionresearch]
ADD FILE
(
NAME = [PartJun],
FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL14.mycompany2\MSSQL\DATA\PartJun.ndf',
SIZE = 5080 KB,
MAXSIZE = UNLIMITED,
FILEGROWTH = 2040 KB
) TO FILEGROUP [June]
ALTER DATABASE [Partitionresearch]
ADD FILE
(
NAME = [PartJul],
FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL14.mycompany2\MSSQL\DATA\PartJul.ndf',
SIZE = 5080 KB,
MAXSIZE = UNLIMITED,
FILEGROWTH = 2040 KB
) TO FILEGROUP [July]
ALTER DATABASE [Partitionresearch]
ADD FILE
(
NAME = [PartAug],
FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL14.mycompany2\MSSQL\DATA\PartAug.ndf',
SIZE = 5080 KB,
MAXSIZE = UNLIMITED,
FILEGROWTH = 2040 KB
) TO FILEGROUP [August]
ALTER DATABASE [Partitionresearch]
ADD FILE
(
NAME = [PartSep],
FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL14.mycompany2\MSSQL\DATA\PartSep.ndf',
SIZE = 5080 KB,
MAXSIZE = UNLIMITED,
FILEGROWTH = 2040 KB
) TO FILEGROUP [September]
ALTER DATABASE [Partitionresearch]
ADD FILE
(
NAME = [PartOct],
FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL14.mycompany2\MSSQL\DATA\PartOct.ndf',
SIZE = 5080 KB,
MAXSIZE = UNLIMITED,
FILEGROWTH = 2040 KB
) TO FILEGROUP [October]
ALTER DATABASE [Partitionresearch]
ADD FILE
(
NAME = [PartNov],
FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL14.mycompany2\MSSQL\DATA\PartNov.ndf',
SIZE = 5080 KB,
MAXSIZE = UNLIMITED,
FILEGROWTH = 2040 KB
) TO FILEGROUP [November]
ALTER DATABASE [Partitionresearch]
ADD FILE
(
NAME = [PartDec],
FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL14.mycompany2\MSSQL\DATA\PartDec.ndf',
SIZE = 5080 KB,
MAXSIZE = UNLIMITED,
FILEGROWTH = 2040 KB
) TO FILEGROUP [December]
--step 4
-- Table Partitioning in SQL Server
USE Partitionresearch
GO
CREATE PARTITION FUNCTION [MonthlyPartition] (date)
AS RANGE RIGHT FOR VALUES ('20190201', '20190301', '20190401',
'20190501', '20190601', '20190701', '20190801',
'20190901', '20191001', '20191101', '20191201');
--step 5
-- Table Partitioning in SQL Server
USE Partitionresearch
GO
CREATE PARTITION SCHEME MonthWisePartition
AS PARTITION MonthlyPartition
TO (January, February, March, April, May, June, July,
August, September, October, November, December
);
--step 6
create table dbo.partitionresearch
(
tranid int identity(1,1),
[Date] date,
Account int,
SeqNumber tinyint,
AlertType int,
IsFirst tinyint,
Indicator1 int,
[time] time
)
on monthwisepartition([date])
--with partitioning help - 40 seconds (as opposed to 3 min 46 sec) , hovered over table scan and didnt see partition count, but clearly partitions (elimination) were used
--did see scalar operators with values 5 and 10 which happens to be where these accounts are partition wise (may and october)
use partitionresearch
select * from dbo.partitionresearch --hoverd over and closest thing to partn help i saw were scalar operators 5 and 10
where (date between '5/1/2019' and '5/31/2019' or date between '10/1/2019' and '10/31/2019') and
account in (1000000,2000000)
------------------------------------------------------------------------------------------------------------------------
--with "partition help" from a lookup table--3 minutes 33 seconds
use partitionresearch
select a.* from dbo.partitionresearch a--hovered over and believe partns wont be used
join [dbo].[monthlookup] b
on a.date=b.date
where account in (1000000,2000000)
------------------------------------------------------------------------------------------------------------------------
--this is the date lookup table which isnt partitioned, thus not aligned
USE [partitionresearch]
GO
/****** Object: Table [dbo].[monthlookup] Script Date: 7/12/2019 6:24:35 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[monthlookup](
[monthid] [int] IDENTITY(1,1) NOT NULL,
[Date] [date] NOT NULL
) ON [PRIMARY]
GO
Run Code Online (Sandbox Code Playgroud)
这在行存储分区堆的产品中不可用。如果您将表更改为具有分区聚集列存储索引,那么您有时可以通过位图过滤器通过行组消除来消除分区,这似乎是您所追求的。
我在这里写了关于这个的博客。引用一小段:
我们知道,根据维度表中的数据,SQL Server 只需要从事实表中读取两个分区即可。理论上的查询优化器能比它做得更好吗?考虑一个分区表最多有 15000 个分区的事实。所有分区值都不能重叠,并且在没有 DDL 操作的情况下它们不会更改。在构建哈希表时,查询优化器可以跟踪哪些分区中至少有一行。在哈希构建结束时,我们将确切知道哪些分区可以包含数据,因此可以在探测阶段跳过其余分区。
也许这没有实现,因为散列构建独立于探测很重要。也许在正确的时间无法保证位图运算符将一直向下推送到扫描,而不是重新分区流运算符。也许这不是一个常见的情况,优化是不值得的。毕竟,您多久加入分区列而不是通过它进行过滤?