Вопрос

Я присоединяюсь к таблице десятки разных раз, и каждый раз я присоединяюсь (или фильтрую) на основе результатов ПОДСТРОКИ одного из столбцов (это строка, но дополненная нулями слева, и я не меня не волнуют последние четыре цифры).В результате, хотя этот столбец проиндексирован и мой запрос будет использовать этот индекс, он выполняет сканирование таблицы, поскольку сама SUBSTRING не индексируется, поэтому SQL Server должен вычислять ее для каждой строки перед ее объединением.

Я ищу любые идеи о том, как ускорить этот процесс.В настоящее время в таблице есть представление (это «SELECT * FROM», просто чтобы дать таблице понятное имя), и я подумываю о добавлении столбца в вычисляемое представление, а затем его индексировании.Я открыт для других предложений, есть какие-нибудь мысли?

БОЛЕЕ ДЕТАЛЬНО:Я должен был поделиться этим с самого начала.Таблица получает репликацию от нашей системы выставления счетов, поэтому редактирование базовой таблицы для добавления вычисляемого столбца невозможно.Любой вычисляемый столбец необходимо будет добавить в представление таблицы.Кроме того, ведущие нули не всегда являются ведущими нулями — иногда это другие данные, которые меня не интересуют.Полагаю, настоящий вопрос заключается в следующем: "Как я могу присоединиться к данным в середине столбца VARCHAR, одновременно используя индекс?Полнотекстовый поиск?"

Уточняю свой примерЯ упрощаю, но, по сути, скажем, я пытаюсь найти значения в столбце со следующими значениями:

00000012345MoreStuff
00000012345Whatever
19834212345
Houses12345837443GGD
00000023456MoreStuff

Меня интересуют строки, в которых SUBSTRING(7,5)="12345", поэтому мне нужны строки 1–4, но не строка 5.Я предлагаю добавить столбец в мое представление «SELECT *», в котором есть эта подстрока, а затем индексировать его на основе этого.Имеет ли это больше смысла?

Это было полезно?

Решение

Предполагая, что у вас есть поля в этом формате:

00Data0007
000000Data0011
0000Data0015

, вы можете сделать следующее:

  • Создайте вычисляемый столбец: ndata AS RIGHT(REVERSE(data), LEN(data) - 4)

    Это преобразует ваши столбцы в следующее:

    ataD00
    ataD000000
    ataD0000
    
  • Создайте индекс для этого столбца

  • Выполните этот запрос для поиска строки Data:

    SELECT  *
    FROM    mytable
    WHERE   ndata LIKE N'ataD%'
            AND SUBSTRING(ndata, LEN(N'ataD') + 1, LEN(ndata)) = REPLICATE('0', LEN(ndata) - LEN('ataD'))
    

    Первое условие будет использовать индекс для грубой фильтрации.

    Второй будет следить за тем, чтобы все ведущие символы (которые стали конечными символами в вычисляемом столбце) были не чем иным, как нулями.

Подробную информацию о производительности смотрите в этой записи в моем блоге:

Обновлять

Если вам просто нужен индекс на SUBSTRING без изменения схемы можно создать представление.

CREATE VIEW v_substring75
WITH SCHEMABINDING
AS
SELECT  s.id, s.data, SUBSTRING(data, 7, 5) AS substring75
FROM    mytable

CREATE UNIQUE CLUSTERED INDEX UX_substring75_substring_id ON (substring75, id)

SELECT  id, data
FROM    v_substring75
WHERE   substring75 = '12345'

Другие советы

Добавить вычисляемый столбец в вашу таблицу и создайте индекс для этого столбца.

ALTER TABLE MyTable
Add Column CodeHead As LEFT(Code,Len(Code)-4)

Затем создайте индекс по этому вопросу.

CREATE INDEX CodeHeadIdx ON MyTable.CodeHead

Можете ли вы перефразировать критерии вашего фильтра в виде утверждения LIKE «что-то%»?(Это применимо к индексу)

Измените столбец на два столбца — данные, к которым вы присоединяетесь, и дополнительные 4 символа.Как вы уже видели, использование частей столбца замедляет работу.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top