Запрос данных из комбинации столбцов с помощью Like (SQL Server 2005/8) - PullRequest
0 голосов
/ 05 января 2012

У меня есть таблица с примерно 15 столбцами, которые можно запрашивать с помощью различных комбинаций. Например, столбцы таблицы - это UserID, LocationID, DepartmentID, CoOrdinate1, CoOrdinate2, CoOrdinate3 ... CoOrdinate15.

Чтобы ускорить поиск комбинации данных, мы создали поле Computed, в котором мы храним значения этих столбцов в формате: UserID :: LocationID :: DepartmentID :: CoOrdinate1: ...: CoOrdinate15: - a значение образца будет выглядеть следующим образом: 1: 100: 20: 22: 39: 94: 29: ..: 9:

Несмотря на то, что это хорошо для извлечения данных при совпадении ключа индекса (оператор = ), мы исследуем лучший метод для получения комбинаций.

Например, если пользователь запрашивает UserID = 1 и CoOrdinate = 15, мы планируем создать условие Like '%: 1 ::% ::% ::% ::% ::% ::% ::%: :% :: 15:%»

.

SQL Server выполняет сканирование индекса для извлечения данных. С точки зрения производительности - есть ли лучший способ решения этой проблемы.

Ответы [ 8 ]

4 голосов
/ 05 января 2012

Из представленной информации выглядит, как будто существует 15 числовых координат для каждой записи в существующей таблице.

Это означает, что существующая таблица не нормализована должным образом.

Я настоятельно рекомендую реструктурировать существующую таблицу так:

UserID
LocationID
DepartmentID
CoOrdinate Number
CoOrdinate Value

(Либо сохраните существующую таблицу без полей CoOrdinate и добавьте новую таблицу с комбинацией UserID, LocationID, DepartmentID, замененной полем ключа из существующей таблицы.)

Это должно позволить гораздо более простой и эффективный запрос данных - индексы в числовых полях намного меньше и быстрее доступны, чем в длинных строковых полях.

3 голосов
/ 05 января 2012

Это вычисленное поле не имеет никакого смысла вообще.LIKE запросы очень медленные.В таблице может быть несколько индексов, в том числе несколько столбцов.Вам будет гораздо лучше полагаться на собственную индексацию SQL Server, чем пытаться свернуть свою собственную.

1 голос
/ 06 января 2012

Если вы настаиваете на вычисленном поле, вы должны построить его следующим образом:

"field1=value1;field2=value2;....;fieldn=valuen"

, то есть

"UserID=123;LocationID=34;DepartmentID=2;CoOrdinate1=56;..."

Вы должны определить полнотекстовый индекс для вычисляемого поля

Например, если пользователь запрашивает UserID = 1 и CoOrdinate = 15, ваше предложение where будет

WHERE CONTAINS(computed_field, "UserID = 1" AND "CoOrdinate = 15")

Вам нужно будет позаботиться о правильной индексации "=" и чисел при определении индекса.Вы должны рассматривать «=» и числа как часть слов, поэтому «UserID = 1» будет одним словом в индексе.

1 голос
/ 05 января 2012

позвольте мне подвести итог:

  • при запросе таблицы в предложении where вы можете иметь произвольную комбинацию столбцов
  • вы можете создать отдельный индекс для каждого столбца, но только один из них будет использоваться для вашего запроса, так как обычные индексы b-дерева не могут быть объединены
  • вы можете создать составные индексы для определенной комбинации столбцов, но эти индексы будут использоваться только теми запросами, у которых есть предложение where, соответствующее столбцам в составном индексе; кроме того, наличие множества широких составных индексов повлечет за собой большие накладные расходы на обслуживание
  • Поскольку вы хотите фильтровать произвольную комбинацию столбцов в ваших запросах, составные индексы не являются опцией: вы не можете создать составной индекс для всех возможных комбинаций столбцов

Как правило, решение этой проблемы заключается в наличии растровых индексов в каждом столбце, поскольку растровые индексы можно комбинировать. К сожалению, SQL Server не поддерживает растровые индексы, но я слышал, что у него есть похожая функция. Я предлагаю вам взглянуть на это:

http://msdn.microsoft.com/en-us/library/bb522541.aspx (В этой статье обсуждается использование растровых индексов при объединении таблиц, но пусть это не смущает вас, они также могут быть полезны в вашем случае использования, когда вы запрашиваете одну таблицу.)

1 голос
/ 05 января 2012

Нет.Поиск LIKE с подстановочными символами всегда будет чепухой.

Вам действительно нужна полная исчерпывающая гибкость поиска?

Если вы ищете '%:1::%::%::%::%::%::%::%::%::15:%', то вы должны искать правильно сWHERE x=1 and y=15 и добавьте соответствующие индексы.

1 голос
/ 05 января 2012

Попробуйте простой подход, я обертываю его в SP:

CREATE PROC Find
@UserId int,
@LocationId int,
....
@CoOrdinate15 int
WITH RECOMPILE
AS
BEGIN
  SET NOCOUNT ON;

  SELECT [what you need]
  FROM YourTable
  WHERE 
      (@UserId IS NULL OR UserId = @UserId) 
  AND (@LocationId IS NULL OR LocationId = @LocationId)
  ...
  AND (@CoOrdinate15 IS NULL OR CoOrdinate15  = @CoOrdinate15)
END

RECOMPILE заставляет оптимизатор Sql Server точно принимать каждый вызов SP с учетом NULL-значных параметров и выбирать правильный индекс длякаждый звонок

0 голосов
/ 05 января 2012

Очень хороший анализ вашего случая. Эрланд Соммарског: Условия динамического поиска в T-SQL

0 голосов
/ 05 января 2012

строит предложение where динамически начиная с where 1=1 и добавляя каждую соответствующую часть как and xx_field = 'value' или and xx_field like '%value%'

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...