Как LIKE "% ..." может искать по индексу?

Я бы ожидал этих двоихSELECTs иметь одинаковый план выполнения и производительность. Так как наLIKEЯ ожидаю сканирования индекса. Когда я запускаю это и смотрю на планы, первыйSELECT ведет себя как положено (при сканировании). Но второеSELECT План показывает индекс поиска и работает в 20 раз быстрее.

Код:

-- 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

Вопрос:

Как SQL Server использует поиск по индексу, когда шаблон начинается с подстановочного знака?

Бонусный вопрос:

Почему конкатенация пустой строки меняет / улучшает план выполнения?

Подробности:

Существует некластеризованный индексAccounts.AccountNumberЕсть и другие индексы, но поиск и сканирование включеныэтот индекс.Accounts.AccountNumber столбец обнуляемыйvarchar(30)Сервер SQL Server 2012

Определения таблиц и индексов:

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]

ПРИМЕЧАНИЕ: вотфактический план выполнения для двух запросов. Имена объектов немного отличаются от приведенного выше кода, потому что я пытался сделать вопрос простым.

Ответы на вопрос(1)

Ваш ответ на вопрос