¿Cómo puede LIKE '% ...' buscar en un índice?

Espero que estos dosSELECTs tener el mismo plan de ejecución y rendimiento. Dado que hay un comodín principal en elLIKE, Espero un escaneo de índice. Cuando ejecuto esto y miro los planes, el primeroSELECT Se comporta como se espera (con un escaneo). Pero el segundoSELECT El plan muestra una búsqueda de índice y se ejecuta 20 veces más rápido.

Código:

-- Uses index scan, as expected:
SELECT 1
    FROM AccountAction
    WHERE AccountNumber LIKE '%441025586401'

-- Uses index seek somehow, and runs much faster:
declare @empty VARCHAR(30) = ''
SELECT 1
    FROM AccountAction
    WHERE AccountNumber LIKE '%441025586401' + @empty

Pregunta:

¿Cómo utiliza SQL Server una búsqueda de índice cuando el patrón comienza con un comodín?

Pregunta extra:

¿Por qué la concatenación de una cadena vacía cambia / mejora el plan de ejecución?

Detalles:

Hay un índice no agrupado enAccounts.AccountNumberHay otros índices, pero tanto la búsqueda como la exploración están activadas.esta índice.losAccounts.AccountNumber la columna es un nullablevarchar(30)El servidor es SQL Server 2012.

Definiciones de tablas e índices:

CREATE TABLE [updatable].[AccountAction](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [AccountNumber] [varchar](30) NULL,
    [Utility] [varchar](9) NOT NULL,
    [SomeData1] [varchar](10) NOT NULL,
    [SomeData2] [varchar](200) NULL,
    [SomeData3] [money] NULL,
    --...
    [Created] [datetime] NULL,
 CONSTRAINT [PK_Account] PRIMARY KEY NONCLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]


CREATE NONCLUSTERED INDEX [IX_updatable_AccountAction_AccountNumber_UtilityCode_ActionTypeCd] ON [updatable].[AccountAction]
(
    [AccountNumber] ASC,
    [Utility] ASC
)
INCLUDE ([SomeData1], [SomeData2], [SomeData3]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]


CREATE CLUSTERED INDEX [CIX_Account] ON [updatable].[AccountAction]
(
    [Created] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

NOTA: Aquí está elreal Plan de ejecución de las dos consultas. Los nombres de los objetos difieren ligeramente del código anterior porque estaba tratando de mantener la pregunta simple.

Respuestas a la pregunta(1)

Su respuesta a la pregunta