Вопрос по индексу SQL Server - поиск адреса - PullRequest
0 голосов
/ 10 апреля 2009

У меня есть таблица, которая может содержать от 10 000 до 10 миллионов строк в течение срока службы приложения. Эта таблица, помимо прочего, содержит информацию NACSZ, и мне нужно написать запрос, который проверяет соответствие NACSZ следующим образом:

select 
    * 
from 
    Profiles 
where 
    FirstName = 'chris' and
    LastName = 'test' and
    Address1 = '123 main st' and
    City = 'chicago' and
    State = 'il' and
    Zip = '11111'

Я пытаюсь оптимизировать таблицу для этого запроса, которая будет выполняться внутри конструкции "if exist ()", и мне не повезло. Без индекса и ~ 110 000 строк тестовых данных я получаю:

Таблица «Профили». Количество сканирований 1, логическое чтение 2021, физическое чтение 0, опережающее чтение - 0, логическое чтение - 0, lob физическое чтение 0, lob упреждающее чтение читает 0.

(затронут 1 ряд)

Время выполнения SQL Server: ЦП время = 16 мс, прошедшее время = 70 мс.

Время выполнения SQL Server: ЦП время = 0 мс, прошедшее время = 1 мс.

План выполнения указывает сканирование кластерного индекса по первичному ключу. Я думал о добавлении индекса для всех значений, но это создаст довольно большой ключ, и я хотел бы попытаться избежать этого, если это возможно. Моя следующая мысль заключалась в том, чтобы индексировать что-то, что будет разумно отличаться между строками, поэтому я попытался выполнить индексацию по имени (хотя я мог использовать адресную строку 1 или zip, например), поэтому я создал индекс:

create index ix_profiles_firstName on profiles(FirstName)

Теперь, когда я запускаю тот же запрос, я получаю

Таблица «Профили». Количество сканирований 1, логическое чтение 171, физическое чтение 0, опережающее чтение - 0, логическое чтение - 0, lob физическое чтение 0, lob упреждающее чтение читает 0.

(затронут 1 ряд)

Время выполнения SQL Server: ЦП время = 0 мс, прошедшее время = 52 мс.

Время выполнения SQL Server: ЦП время = 0 мс, прошедшее время = 1 мс.

Очевидно, что индексирование имени имело ОГРОМНОЕ отличие. У меня вопрос, как мне решить, следует ли мне индексировать имя против фамилии против адреса против почтового индекса? Есть ли команда, которую я могу запустить поверх моих образцов данных, которая скажет мне уникальность значений в каждом поле? Насколько я понимаю, я должен попытаться индексировать столбец с наибольшей уникальностью, чтобы индекс работал лучше, верно?

Ответы [ 5 ]

3 голосов
/ 10 апреля 2009

Для вашего запроса вы должны создать составной индекс для всех столбцов: (FirstName, LastName, address1, city, state, zip)

Если вы хотите, чтобы в SQL Server использовался определенный индекс, введите:

SELECT  *
FROM    Profiles WITH (INDEX (index_name))
WHERE 
        FirstName = 'chris' and
        LastName = 'test' and
        Address1 = '123 main st' and
        City = 'chicago' and
        State = 'il' and
        Zip = '11111'

Мой вопрос: как мне решить, следует ли мне индексировать имя, фамилию, адрес или почтовый индекс?

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

Обратите внимание, что вы можете эффективно фильтровать первые столбцы из индекса, например:

SELECT  *
FROM    Profiles
WHERE   FirstName = 'chris'

будет использовать индекс для поиска по FirstName,

SELECT  *
FROM    Profiles
WHERE   FirstName = 'chris'
        AND LastName = 'test'

будет использовать индекс для поиска по FirstName и LastName,

SELECT  *
FROM    Profiles
WHERE   FirstName = 'chris'
        AND City = 'chicago'

будет использовать индекс для поиска только по FirstName (вы не фильтруете по LastName, есть пробел, и индекс не может использоваться для поиска по другим столбцам)

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

SELECT   COUNT(DISTINCT FirstName) / COUNT(*)
FROM     Profiles

покажет вам FirstName обратную селективность.

Чем больше это значение, тем менее эффективен индекс.

Насколько я понимаю, я должен попытаться проиндексировать столбец с максимальной уникальностью, чтобы индекс работал лучше, верно?

Да.

Опять же, в вашем случае вы должны проиндексировать все столбцы. Самая большая уникальность наверняка для всех столбцов, взятых вместе.

1 голос
/ 10 апреля 2009

У вас есть несколько вариантов. Как указал Кассной, вы можете создать составной индекс. Другой вариант, который я использовал в несколько ином сценарии, заключался в создании уникального ключа на основе данных. В моей ситуации я сравнивал адреса и пытался предотвратить дублирование (так как мы будем геокодировать любой новый адрес и каждое геокодирование будет стоить $$).

В любом случае, по сути, мы взяли ключевые части адреса и создали новый ключ (Address, State & Zip). Вы можете сделать то же самое, а затем сравнить только с одним столбцом.

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

1 голос
/ 10 апреля 2009

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

1 голос
/ 10 апреля 2009

Мой вопрос: как мне решить, следует ли мне индексировать имя, фамилию, адрес или почтовый индекс?

Соберите все запросы, которые вы намереваетесь использовать (если это единственный, все готово). Затем передайте запросы в качестве рабочей нагрузки мастеру настройки индекса и посмотрите рекомендации.

Насколько я понимаю, я должен попытаться проиндексировать столбец с максимальной уникальностью, чтобы индекс работал лучше, верно?

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

0 голосов
/ 10 апреля 2009

В дополнение к другим ответам ...

Какую комбинацию фильтров вы будете использовать? Попробуйте охватить самые популярные комбинации.

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