SQLServer индексирует несколько столбцов для одного результата - PullRequest
1 голос
/ 27 января 2011

У меня есть большая таблица (100000+ строк), в которой 4 столбца имеют одинаковое концептуальное значение.

Скажем, запись представляет собой соревнование между игроками, чьи имена находятся в столбцах A, B, C и D.А A + B играет против C + D.

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

... Где (Столбец A как «DOE%» ИЛИ Столбец B как «DOE%» ИЛИ Столбец C как «DOE%» ИЛИ Столбец D как «DOE%») И ... Другие условия ...

И так как таблица огромна, мне нужен способ индексировать все эти 4 столбца.

Я знаю, что могу создать дополнительную таблицу, в которой хранится имя каждого игрока вместе с его позицией A, B, C илиD и RowID главной таблицы, но я подозреваю, что должен быть лучший способ ...

Любая подсказка от гуру SQLServer?

Ответы [ 3 ]

3 голосов
/ 27 января 2011

Просто поместите индекс в каждый столбец (всего 4 индекса).

Таким образом, сервер может запросить каждый индекс и собрать результаты в соответствии с условиями.Это позволяет выполнять широкий спектр запросов и все еще достаточно быстро.

1 голос
/ 27 января 2011
"I know I can create a secondary table storing each player name together
 with his position A, B, C or D and the main table's RowID, but I suspect
 there should be a better way..."

В реляционной базе данных это лучше .Причина в том, что это упрощает код вашего приложения и вашу функцию DBA:

1) Вопрос по индексу?Индекс по идентификатору игрока.

2) Запрос?Выберите ... из playerGames, где playerId = X

3) Текущий дизайн допускает только один простой запрос, находя всех игроков в позиции A, B, C или D, и это все еще легко: Выбрать.... from ... where position = 'A'

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

0 голосов
/ 27 января 2011

Я бы поместил индекс для каждого столбца с идентификатором в качестве включенного столбца, как указано @ttoni, а затем создал бы покрывающий индекс для идентификатора и включил 4 столбца, а затем выполнил бы этот запрос:

declare @string varchar(50)
set @string='Karen'

select
    a.ID
    A,
    B,
    C,
    D
from dbo.Players a
    inner join
    (
        select
            ID
        from dbo.Players
        where A = @string

        union all
        select
            ID
        from dbo.Players
        where B = @string

        union all
        select
            ID
        from dbo.Players
        where C = @string

        union all
        select
            ID
        from dbo.Players
        where D = @string
    ) b
        on a.ID=b.ID

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

вот первый индекс:

CREATE NONCLUSTERED INDEX [IDX_A] ON [dbo].[Players] 
(
    [A] ASC
)
INCLUDE ( [ID]) WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO

и вот индекс покрытия:

CREATE NONCLUSTERED INDEX [IDX_All] ON [dbo].[Players] 
(
    [ID] ASC
)
INCLUDE ( [A],
[B],
[C],
[D]) WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...