我有一个按月分区的表(partmonth int)。用于查询表的存储过程仅接收日期范围。我需要找到一种方法来获取日期范围内的所有月份数,并将它们传递到分区表的(1,2 ...)子句中。我已经尝试创建月份数的临时表并使用where in(从#tmp中选择monthnumber),但这似乎在每条记录上执行#tmp或扫描所有分区。我也尝试将分区表加入到tmp表中,但这似乎也扫描了所有分区。我假设查询优化器需要partmonth的硬值。
查询获取所有月份数字:
declare @months varchar(100)
select d.* into #tmp
from
(select distinct MonthNumber from [date] where [date] between '1/1/2010' and '4/1/2010') d
select @months = coalesce(@months + ', ', '') + cast(monthnumber as varchar(2)) from #tmp
select @months
drop table #tmp
现在我需要能够在select语句中使用这些月号,以便触发正确的分区。
以下不起作用的东西: 从[交易]中选择* (@months)中的partmonth
答案 0 :(得分:1)
我发现使用“where in(...)”的select语句可用于表分区过滤。我看到的表扫描是由于使用了其他标准,即使我传入(10)中的位置,我也会进行扫描。
我还发现你也可以使用分区功能进行分区选择,但是在我的环境和架构中,它引起了索引扫描和索引搜索。
DECLARE @months TABLE (MonthNumber int)
insert into @months
select distinct MonthNumber from [date] where [date] between '10/1/2010' and '10/7/2010'
select * from [transaction] t
WHERE $Partition.TransactionPartitionFunction(t.partmonth) in (select monthnumber from @months)
实际执行计划使用set statistics xml on重新启动。 没有在哪里:
<RunTimePartitionSummary>
<PartitionsAccessed PartitionCount="13">
<PartitionRange Start="1" End="13" />
</PartitionsAccessed>
</RunTimePartitionSummary>
在哪里:
<RunTimePartitionSummary>
<PartitionsAccessed PartitionCount="1">
<PartitionRange Start="10" End="10" />
</PartitionsAccessed>
</RunTimePartitionSummary>