Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Por que isso é uma varredura de índice e não uma busca de índice?


Ele está usando um Index Scan principalmente porque também está usando um Merge Join. O operador Merge Join requer dois fluxos de entrada classificados em uma ordem compatível com as condições de Join.

E está usando o operador Merge Join para realizar seu INNER JOIN porque acredita que isso será mais rápido que o operador Nested Loop Join mais típico. E provavelmente está certo (geralmente está), usando os dois índices que escolheu, tem fluxos de entrada que são pré-classificados de acordo com sua condição de junção (LocationID). Quando os fluxos de entrada são pré-ordenados assim, as Junções de Mesclagem são quase sempre mais rápidas do que as outras duas (Junções de Loop e Hash).

A desvantagem é o que você notou:parece estar digitalizando todo o índice, então como isso pode ser mais rápido se estiver lendo tantos registros que nunca poderão ser usados? A resposta é que as varreduras (devido à sua natureza sequencial) podem ler de 10 a 100 vezes mais registros/segundo do que buscas.

Agora, Seeks geralmente vencem porque são seletivos:eles obtêm apenas as linhas que você solicita, enquanto os Scans são não seletivos:eles devem retornar todas as linhas do intervalo. Mas como as varreduras têm muito taxa de leitura mais alta, eles podem frequentemente vencer Buscas, desde que a proporção de Linhas Descartadas para Linhas Correspondentes seja menor do que a proporção de Varrer linhas/s VS. Procurar linhas/seg.

Perguntas?

OK, me pediram para explicar mais a última frase:

Uma "Linha Descartada" é aquela que o Scan lê (porque tem que ler tudo no índice), mas que será rejeitada pelo operador Merge Join, porque não tem uma correspondência do outro lado, possivelmente porque o A condição da cláusula WHERE já a excluiu.

"Linhas Correspondentes" são aquelas que ele lê que realmente correspondem a algo no Merge Join. Essas são as mesmas linhas que seriam lidas por um Seek se o Scan fosse substituído por um Seek.

Você pode descobrir o que existem observando as estatísticas no Plano de consulta. Vê aquela seta enorme e gorda à esquerda do Index Scan? Isso representa quantas linhas o otimizador pensa que lerá com o Scan. A caixa de estatísticas da Varredura de Índice que você postou mostra que as Linhas Reais retornadas são cerca de 5,4 M (5.394.402). Isso é igual a:
TotalScanRows = (MatchingRows + DiscardedRows)

(Nos meus termos, de qualquer maneira). Para obter as linhas correspondentes, observe as "linhas reais" relatadas pelo operador Merge Join (talvez seja necessário tirar o TOP 100 para obter isso com precisão). Depois de saber disso, você pode obter as linhas Descartadas por:
DiscardedRows = (TotalScanRows - MatchingRows)

E agora você pode calcular a proporção.