简体   繁体   English

查询包含简单功能时将忽略Azure SQL表分区

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM