[英]Azure SQL table partitions Ignored when queries contain simple function
Using Azure SQL Server database. 使用Azure SQL Server数据库。 I have a few tables partitioned on a 90 day date boundary.
我有一些表在90天的日期范围内分区。 We have a stored procedure to shift data to maintain the proper partition breakpoint/range.
我们有一个存储过程来移位数据,以保持适当的分区断点/范围。 I'm using a small function to provide the proper date breakpoint for my queries so I don't have to constantly update all my views.
我正在使用一个小函数为查询提供正确的日期断点,因此我不必不断更新所有视图。
But just by virtue of using that function in my queries, partitioning is ignored. 但是仅仅由于在查询中使用了该功能,分区就被忽略了。 Do I have no choice but to put hard-coded values in my queries everywhere and constantly modify them?
我别无选择,只能在所有地方的查询中放入硬编码的值并不断对其进行修改吗?
Here is a sample that reproduces the problem. 这是重现该问题的示例。
Update : After changing the PartitionDate
function below according to the marked answer, it was fine for a short time (partition elimination occurred). 更新 :根据标记的答案更改了以下
PartitionDate
函数后,短时间没问题(发生了分区消除)。 Then, queries started sucking again. 然后,查询又开始变得糟透了。 When I ran simple queries filtered by the date function, partitions were no longer eliminated.
当我运行由date函数过滤的简单查询时,不再消除分区。
------------------------------- setup
-- Create functions PartitionDate and PartitionQueryDate
create function PartitionDate() returns date as
begin
return GETDATE() - 91 -- returns 1/4/2019 today
end
go
create function PartitionQueryDate() returns date as
begin
return GETDATE() - 90 -- returns 1/5/2019
end
go
-- Create partition func and scheme using above functions
CREATE PARTITION FUNCTION order_pf (smalldatetime) AS RANGE RIGHT FOR VALUES (dbo.PartitionDate())
CREATE PARTITION SCHEME order_ps AS PARTITION order_pf ALL TO ([PRIMARY])
-- Create Order (pk, OrderDate, Fk), Customer (pk) tables. Order is partitioned
create table Customer
(
id int primary key identity(1,1),
FirstName varchar(255) not null
)
create table [Order]
(
id int identity(1,1), OrderDate smalldatetime not null,
CustomerId int not null,
CONSTRAINT [FK_Orders_Customer] FOREIGN KEY ([CustomerId]) REFERENCES Customer([id])
) on order_ps(OrderDate);
-- Add in indexes to Order: only OrderDate on the partition func
CREATE CLUSTERED INDEX [Order_OrderDate] ON [Order]([OrderDate] ASC) ON [order_ps] ([OrderDate]);
CREATE NONCLUSTERED INDEX [FK_Order_Customer] ON [Order](CustomerId, OrderDate) ON [order_ps] ([OrderDate]) -- seems to work the same with or without the partition reference.
go
-- Add some data before and after the partition break
insert Customer values ('bob')
insert [Order] values('12-31-2018', SCOPE_IDENTITY())
insert Customer values ('hank')
insert [Order] values('1-6-2019', SCOPE_IDENTITY())
---------------------------- test
-- verify a row per partition:
SELECT $PARTITION.order_pf(OrderDate) as Partition_Number, COUNT(*) as Row_Count
FROM [Order]
GROUP BY $PARTITION.order_pf(OrderDate)
-- Simple queries with actual execution plan turned on. The queries are logically equivalent.
select COUNT(1) from [Order] where OrderDate > '1-5-2019' -- Index seek Order_OrderDate; actual partition count 1
select COUNT(1) from [Order] where OrderDate > dbo.PartitionQueryDate() -- Index seek Order_OrderDate; actual partition count 2
-- Cleanup
drop table if exists [Order]
drop table if exists Customer
drop partition scheme order_ps
drop partition function order_pf
drop function if exists PartitionDate
drop function if exists PartitionQueryDate
One workaround would be to assign the function result to a variable first. 一种解决方法是先将函数结果分配给变量。
declare @pqd smalldatetime = dbo.PartitionQueryDate();
select COUNT(1) from [Order] where OrderDate > @pqd
Another option would be to use an inline TVF 另一种选择是使用嵌入式TVF
CREATE FUNCTION dbo.PartitionQueryDateTVF ()
RETURNS TABLE
AS
RETURN
(
SELECT CAST(CAST( GETDATE() - 90 AS DATE) AS SMALLDATETIME) AS Date
)
GO
SELECT COUNT(1) from [Order] where OrderDate > (SELECT Date FROM dbo.PartitionQueryDateTVF())
This may be something that is improved with inline scalar UDFs but I'm not in a position to test this at the moment 内联标量UDF可能会对此有所改善,但目前我无法对此进行测试
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.