Eu tenho a seguinte exibição indexada definida no SQL Server 2008 (você pode baixar um esquema funcional da gist para fins de teste):
CREATE VIEW dbo.balances
WITH SCHEMABINDING
AS
SELECT
user_id
, currency_id
, SUM(transaction_amount) AS balance_amount
, COUNT_BIG(*) AS transaction_count
FROM dbo.transactions
GROUP BY
user_id
, currency_id
;
GO
CREATE UNIQUE CLUSTERED INDEX UQ_balances_user_id_currency_id
ON dbo.balances (
user_id
, currency_id
);
GO
user_id
,, currency_id
e transaction_amount
são todos definidos como NOT NULL
colunas em dbo.transactions
. No entanto, quando olho para a definição de exibição no Pesquisador de Objetos do Management Studio, ela marca as colunas como balance_amount
e -able na exibição.transaction_count
NULL
Examinei várias discussões, sendo esta a mais relevante, que sugerem que algumas funções aleatórias podem ajudar o SQL Server a reconhecer que uma coluna de exibição é sempre NOT NULL
. No entanto, não é possível embaralhar esse tipo, pois expressões em funções agregadas (por exemplo, um ISNULL()
over the SUM()
) não são permitidas em visualizações indexadas.
Existe alguma maneira eu posso ajudar SQL Server reconhecer que
balance_amount
etransaction_count
sãoNOT NULL
-able?Caso contrário, devo ter alguma preocupação sobre o fato de essas colunas serem identificadas por engano como
NULL
-able?As duas preocupações em que consigo pensar são:
- Quaisquer objetos de aplicativo mapeados para a exibição de saldos estão recebendo uma definição incorreta de um saldo.
- Em casos muito limitados, certas otimizações não estão disponíveis para o Query Optimizer, pois não há garantia da exibição de que essas duas colunas estão
NOT NULL
.
Alguma dessas preocupações é um grande negócio? Há outras preocupações que devo ter em mente?
fonte
Respostas:
Parece-me que o SQL Server tem uma suposição geral de que um agregado pode produzir um
null
mesmo que os campos nos quais ele opera sejamnot null
. Isto é obviamente verdade em certos casos:E também é verdade nas versões generalizadas de
group by
likecube
Este caso de teste mais simples ilustra o ponto em que qualquer agregado é interpretado como sendo anulável:
Na IMO, essa é uma limitação (embora menor) do SQL Server - alguns outros RDBMSs permitem a criação de certas restrições nas exibições que não são impostas e existem apenas para fornecer pistas para o otimizador, embora eu ache que a 'exclusividade' é mais provável. ajudar a gerar um bom plano de consulta além da 'nulidade'
Se a nulidade da coluna for importante, talvez para uso com um ORM, considere agrupar a exibição indexada em outra exibição que simplesmente garanta a não nulidade usando
ISNULL
:fonte
Acho que não há como você forçar o SQL Server a reconhecer essas colunas como não anuláveis, mesmo que claramente não. Você pode tentar alterar a ordem de como define
ISNULL
/ emCOALESCE
torno da expressão internaSUM()
, por exemplo, mas isso não vai ajudar.Também não acredito que haja otimizações que você perderá - essas colunas não estão indexadas no momento, por isso não é como se o otimizador pudesse escolher um método de acesso diferente para determinar, digamos, todos os
balance_amount
valores> 10000. pode ser uma situação em que, se você criar um índice não agrupado em uma dessas colunas, poderá obter estimativas um pouco melhores do que se o índice não estiver lá, mas isso não tem nada a ver com a nulidade.Eu não ficaria muito preocupado com isso do ponto de vista de desempenho. Voltei e observei várias visualizações indexadas que criei ao longo dos anos e essas colunas de agregação são todas anuláveis. Eles executam muito bem.
Quanto ao mapeamento de objetos, novamente, eu não estaria muito preocupado com isso. Como o aplicativo não pode atualizar a exibição indexada, não importa se acha que
balance_amount
pode sernull
. Ele nunca receberá umnull
e não pode tentar escrever umnull
, então<shrug>
.fonte