2009-08-24 2 views
15

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

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

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

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

00000MoreStuff 
00000Whatever 
19834212345 
Houses12345837443GGD 
00000023456MoreStuff 

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

+0

Чтобы сделать 'JOIN' использование индекса, вы должны преобразовать свой столбец так, чтобы он начинался с условия, которое вы ищете. На данный момент ваш алгоритм слишком расплывчатый. «Ведущие нули, которые не всегда являются ведущими нулями», трудно объяснить SQL Server. Индекс FULLTEXT может использоваться для поиска префиксов внутри слов (в отличие от целых столбцов), но вы все равно должны разделить ваши данные на слова. Не могли бы вы более четко определить свой алгоритм поиска? – Quassnoi

+0

Если вы ищете индекс _SEEK_, то вам также нужно знать, достаточно ли у вас данных. То есть, каково отношение общих значений в базе данных по сравнению с количеством значений distict. «Перекрестная точка» на самом деле довольно низкая (в зависимости от ширины таблицы). Кроме того, если ваш индекс не включает столбцы, которые вы выбираете, количество чтений, которые вы делаете в результате поиска в закладке, заставит SQL Server игнорировать ваш новый индекс. Можете ли вы предоставить подробную информацию об избирательности/списке выбора? – Anon246

ответ

13

Если у вас есть свои поля в этом формате:

00Data0007 
000000Data0011 
0000Data0015 

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

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

    Это трансформирует ваши столбцы:

    ataD00 
    ataD000000 
    ataD0000 
    
  • Создание индекса по этому столбцу

  • Issue этот запрос для поиска строки Data:

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

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

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

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

Update

Если вы просто хотите индекс на 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' 
+0

Это то, с чем я закончу. Я просто схематирую представление, и тогда мне будет хорошо идти. Спасибо за указатель. – SqlRyan

1

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

0

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

6

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

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

Затем создайте указатель на этом.

CREATE INDEX CodeHeadIdx ON MyTable.CodeHead 

 Смежные вопросы

  • Нет связанных вопросов^_^