Diferença entre procurar predicado e predicado

12

Estou tentando ajustar o desempenho de uma consulta que temos no SQL Server 2014 Enterprise.

Abri o plano de consulta real no SQL Sentry Plan Explorer e posso ver em um nó que ele tem um Predicado de Busca e também um Predicado

Qual é a diferença entre Seek Predicate e Predicate ?

insira a descrição da imagem aqui

Nota: Percebo que há muitos problemas com este nó (por exemplo, as linhas Estimativa vs Atual, a E / S residual), mas a questão não está relacionada a nada disso.

Greg
fonte
3
O predicado de busca auxilia na associação, filtrando apenas as linhas que também são encontradas na outra tabela (que você editou). O predicado (um predicado residual) , em seguida, elimina as linhas com o estatuto específico de 2.
Aaron Bertrand
5
Rob Farley afirmou o seguinte em um comentário aqui :The Seek Predicate can be used to find the start of the RangeScan and then when to stop, while the Predicate is the "check" that is applied to every row in the Range.
Aaron Bertrand

Respostas:

18

Vamos lançar um milhão de linhas em uma tabela temporária, juntamente com algumas colunas:

CREATE TABLE #174860 (
PK INT NOT NULL, 
COL1 INT NOT NULL,
COL2 INT NOT NULL,
PRIMARY KEY (PK)
);

INSERT INTO #174860 WITH (TABLOCK)
SELECT RN
, RN % 1000
, RN % 10000
FROM 
(
    SELECT TOP 1000000 ROW_NUMBER () OVER (ORDER BY (SELECT NULL)) RN
    FROM   master..spt_values v1,
           master..spt_values v2
) t;

CREATE INDEX IX_174860_IX ON #174860 (COL1) INCLUDE (COL2);

Aqui eu tenho um índice clusterizado (por padrão) na PKcoluna. Há um índice não clusterizado COL1que possui uma coluna-chave de COL1e inclui COL2.

Considere a seguinte consulta:

SELECT *
FROM #174860
WHERE PK >= 15000 AND PK < 15005
AND COL2 = 5000;

Aqui não estou usando BETWEENporque Aaron Bertrand está por aí com essa questão.

Como o SQL Server deve otimizar essa consulta? Bem, eu sei que o filtro PKativado reduzirá o conjunto de resultados para cinco linhas. O servidor SQL pode usar o índice em cluster para ir para essas cinco linhas em vez de ler todos os milhões de linhas da tabela. No entanto, o índice clusterizado tem apenas a coluna PK como uma coluna-chave. Depois que a linha é lida na memória, precisamos aplicar o filtro COL2. Aqui, PKé um predicado de busca e COL2é um predicado.

insira a descrição da imagem aqui

O SQL Server localiza cinco linhas usando o predicado de busca e reduz ainda mais essas cinco linhas para uma linha com o predicado normal.

Se eu definir o índice clusterizado de maneira diferente:

CREATE TABLE #174860 (
PK INT NOT NULL, 
COL1 INT NOT NULL,
COL2 INT NOT NULL,
PRIMARY KEY (COL2, PK)
);

E execute a mesma consulta, obtenho resultados diferentes:

insira a descrição da imagem aqui

Nesse caso, o SQL Server pode procurar usando as duas colunas na WHEREcláusula. Exatamente uma linha é lida da tabela usando as colunas-chave.

Para mais um exemplo, considere esta consulta:

SELECT *
FROM #174860
WHERE COL1 = 500
AND COL2 = 3545;

O índice IX_174860_IX é um índice de cobertura porque contém todas as colunas necessárias para a consulta. No entanto, apenas COL1é uma coluna chave. O SQL Server pode procurar com essa coluna encontrar as 1000 linhas com um COL1valor correspondente . Ele pode filtrar ainda mais essas linhas na COL2coluna para reduzir o resultado final definido para 0 linhas.

insira a descrição da imagem aqui

Joe Obbish
fonte