Eu tenho a seguinte tabela particionada
create table T (Month char(6), ID int, .... primary key (ID, Month)) on psMonth(Month)
A função de partição é
CREATE PARTITION FUNCTION [pfMonth](char(6)) AS
RANGE RIGHT FOR VALUES (N'200001', .... N'200705', N'200706', N'200707', ....)
No entanto, a contagem real de partições da consulta a seguir é 260 em vez de 1?
select count(*)
from T (nolock)
where Month = '200706'
O plano de execução é
|--Calcular escalar(DEFINE:([Expr1004]=CONVERT_IMPLICIT(int,[globalagg1006],0))) |--Stream Aggregate(DEFINE:([globalagg1006]=SUM([partialagg1005]))) |--Paralelismo(Gather Streams) |--Stream Aggregate(DEFINE:([partialagg1005]=Contagem(*))) |--Clustered Index Scan(OBJECT:([DB].[dbo].[T].[PK_T]), WHERE:([DB].[dbo].[T].[Mês]=[@1] ))
Atualização:
a consulta é executada rapidamente e a contagem real de partições é 1 se eu executar a consulta a seguir.
select count(*), $partition.pfMonth(Month)
from T with (nolock)
where Month = '200706'
group by $partition.pfMonth(Month)
Atualização 2:
A consulta a seguir também verifica apenas uma partição.
select count(*), min($partition.pfByMonth(Month))
from T
where Month = '200707'
Atualização 3:
o SQL original verifica apenas uma partição agora. Não faço ideia do que aconteceu. A única diferença é que mais dados foram inseridos na tabela.
Resposta: Usei um CTE que envolveu a tabela. E resolveu o problema causado pela precedência de tipo. (No entanto, o CTE não resolveu o problema no início, a coisa toda é estranha e imprevisível.)
Sua coluna é do tipo
CHAR(6)
. Seu filtro é do tipoVARCHAR
(talvez contra-intuitivo, mas é o que é o literal constante'200706'
). As regras de Data Type Precedence determinam que a comparação ocorra usando o tipo com maior precedência, ou seja. o tipo VARCHAR. Este é um tipo diferente da função de particionamento, portanto você não obtém a eliminação da partição.Tente isso em vez disso:
Seu plano deve obter um filtro de eliminação de particionamento.
Isso está diretamente relacionado à sua outra pergunta.
Você não tem um índice apenas em sua chave de partição, é a segunda chave em seu PK. Por causa disso, o mecanismo precisa verificar cada linha. Se você tivesse um índice nesse campo, ele poderia verificar apenas o índice.