Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Индекс по нескольким полям / 16 сообщений из 16, страница 1 из 1
21.02.2002, 12:29
    #32023654
DennisL
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс по нескольким полям
Если создан один индекс по нескольким полям таблицы (для ускорения выборок), он будет ускорять поиск по любому из полей или только по их комбинации ...

Например : я себе с трудом представляю что получаеться если создать например индекс по двум полям
по одному asc а по другому desc ... ?
...
Рейтинг: 0 / 0
21.02.2002, 12:52
    #32023659
Andrew
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс по нескольким полям
только по комбинации
...
Рейтинг: 0 / 0
21.02.2002, 12:58
    #32023660
Genady
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс по нескольким полям
Я сейчас не помню точно, но как мне кажется не только по комбинации.
В общем используйте ITW и не мучайтесь
...
Рейтинг: 0 / 0
21.02.2002, 13:48
    #32023666
MadDog
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс по нескольким полям
2 DennisL:
Поиск может быть ускорен по любому полю. Все зависти от оптимизатора. Он может решить вообще использовать table scan (и не всегда зря).
По большому счету Genady прав - Index Tuning Wisard обычно решает проблемы.

PS sql2k. В 7.0 было немного по-другому, по-моему.
...
Рейтинг: 0 / 0
21.02.2002, 15:08
    #32023673
AlexSh
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс по нескольким полям
Думаю, что по первому столбцу индекса и по комбинации первого и второго оптимизация будет точно.
...
Рейтинг: 0 / 0
22.02.2002, 16:59
    #32023788
Garya
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс по нескольким полям
AlexSh дал ответ, который звучал неуверенно, но в отличие от всех других был правильным.
Индекс по комбинации полей используется если в запросе перечислены первые поля индекса. Если какое-либо поле начиная от первого в запросе пропущено, индекс задействован не будет. Это во-первых.
Во-вторых, составной индекс использует больше места для хранения информации об одной записи (значения индексируемых полей). Следовательно, составной индекс, у которого задействовано в запросе только одно (первое поле), будет работать медленнее из-за перебора бОльшего количества страниц индекса, нежели при использовании индекса по одному полю.
Резюме. Составные индексы имеет смысл использовать только в тех случаях, когда запросы всегда строятся с использованием задействованной в индексе комбинации полей.
...
Рейтинг: 0 / 0
24.02.2002, 11:59
    #32023838
MadDog
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс по нескольким полям
Интересная тема.

2 Garya:
Пока я работал с 7.0, я полагал также как и Вы. И для этого были основания, всё подтверждалось практикой. В sql2k я столкнулся с другим поведением. Приведу пример.
sql2k sp2 on NT 4.0 sp6a.
Таблица tmpA - 25492 записи, 38 полей. Поля Id, Cli, Acc имеют тип int.

-- Строим индекс по Id:
create unique clustered index PK_tmpA on tmpA(Id)
GO
-- В качестве текстовых используем эти три выборки:
select *
from tmpA
where Cli = 2667 and Acc = 30

select *
from tmpA
where Cli = 2667

select *
from tmpA
where Acc = 30 and Currency = 1

GO

-- При помощи SET SHOWPLAN_TEXT ON получем, как и ожидалось, использование кластерного индекса во всех трех случаях:
|--Clustered Index Scan(OBJECT[Buh].[dbo].[tmpA].[PK_tmpA]), WHERE[tmpA].[Acc]=Convert([@2]) AND [tmpA].[Cli]=Convert([@1])))

|--Clustered Index Scan(OBJECT[Buh].[dbo].[tmpA].[PK_tmpA]), WHERE[tmpA].[Cli]=Convert([@1])))

|--Clustered Index Scan(OBJECT[Buh].[dbo].[tmpA].[PK_tmpA]), WHERE[tmpA].[Acc]=Convert([@1]) AND [tmpA].[Currency]=Convert([@2])))


-- И, соответствующие результаты, сами записи выборки опущены.

(1 row(s) affected)
Table 'tmpA'. Scan count 1, logical reads 659, physical reads 88, read-ahead reads 356.

(54 row(s) affected)
Table 'tmpA'. Scan count 1, logical reads 659, physical reads 0, read-ahead reads 0.

(1 row(s) affected)
Table 'tmpA'. Scan count 1, logical reads 659, physical reads 0, read-ahead reads 0.




-- создаем составной индекс:
create index IX_tmpA_Cli_Acc on tmpA(Cli asc, Acc desc)
GO
-- Предполагаем использование индекса IX_tmpA_Cli_Acc только в первых двух запросах, однако:

-- При помощи SET SHOWPLAN_TEXT ON во всех трех случаях получем использование индекса:
|--Bookmark Lookup(BOOKMARK[Bmk1000]), OBJECT[Buh].[dbo].[tmpA]))
|--Index Seek(OBJECT[Buh].[dbo].[tmpA].[IX_tmpA_Cli_Acc]), SEEK[tmpA].[Cli]=Convert([@1]) AND [tmpA].[Acc]=Convert([@2])) ORDERED FORWARD)

|--Bookmark Lookup(BOOKMARK[Bmk1000]), OBJECT[Buh].[dbo].[tmpA]))
|--Index Seek(OBJECT[Buh].[dbo].[tmpA].[IX_tmpA_Cli_Acc]), SEEK[tmpA].[Cli]=Convert([@1])) ORDERED FORWARD)

|--Filter(WHERE[tmpA].[Currency]=Convert([@2])))
|--Bookmark Lookup(BOOKMARK[Bmk1000]), OBJECT[Buh].[dbo].[tmpA]))
|--Index Scan(OBJECT[Buh].[dbo].[tmpA].[IX_tmpA_Cli_Acc]), WHERE[tmpA].[Acc]=Convert([@1])))

-- Соответствующие выборки:
(1 row(s) affected)
Table 'tmpA'. Scan count 1, logical reads 5, physical reads 0, read-ahead reads 0.

(54 row(s) affected)
Table 'tmpA'. Scan count 1, logical reads 188, physical reads 0, read-ahead reads 0.

(1 row(s) affected)
Table 'tmpA'. Scan count 1, logical reads 52, physical reads 0, read-ahead reads 0.


Информация, получаемая с помощью SET SHOWPLAN_TEXT ON, показывает использование составного индекса, а уменьшение показателя logical reads, по сравнению с теми же выборками, но в отсутствии составного индекса, говорит об эффективном его использовании во всех трех случаях. Хотя, конечно, выборка с условием where по первому полю работает эффективнее чем по последнему, а их комбинация - лучше всех.

У кого есть возможность, прошу повторить что-либо подобное. Может быть я что-то упустил.
...
Рейтинг: 0 / 0
26.02.2002, 09:04
    #32023908
qu-qu
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс по нескольким полям
2 MadDog:

Никакого противоречия в приведенном вами примере по отношению к мнению Garya - я не увидел...
Там же четко все написано (для составного индекса):
- первые 2 условия: Index Seek ;
- последнее условие: Index Scan .
Другое дело, что вхождение поля ACC в составной индекс - позволяет оптимизатору выбрать Scan не по всей таблице (читай - кластерному индексу ID), а по ее подмножеству... (по-моему в 7-рке такое уже было реализовано).

З.Ы. Совсем странно при этом выглядят показатели "логических чтений" для поиска и сканирования по составному индексу (188/52), похоже, что поле ACC в данной таблице - имеет селективность на порядок выше, чем поле CLI? В таком случае, при создании составного индекса - не следует ли указывать его первым в перечислении create index IX_tmpA_Cli_Acc on tmpA(Acc desc, Cli asc) ? Хотя, может быть - как раз и нет... (что толку от его селективности, если одно "голое" условие по CLI - выдаст SCAN-ов в 10 раз больше?)
...
Рейтинг: 0 / 0
04.03.2002, 05:22
    #32024250
MadDog
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс по нескольким полям
2 qu-qu:
Тут где-то звучал афоризм, не помню чей - не удалось найти, "Читай внимательно и до конца". К этому остается только добавить - "Читай сначала".
Был вопрос:
"индекс по нескольким полям таблицы ... будет ускорять поиск по любому из полей[?]"
Прозвучал ответ:
Индекс по комбинации полей используется если в запросе перечислены первые поля индекса. Если какое-либо поле начиная от первого в запросе пропущено, индекс задействован не будет.
Я попытался показать что может быть использовано любое подходящее поле из составного индекса, в том числе не первое. Зависит это, как Вы правильно заметили, от "селективности". А уж как там этот индекс обрабатывается (scan или seek) - какая разница, если это быстрее чем table scan? Ведь вопрос (
"Читай сначала") звучал именно так: "будет ускорять"? Ответ - будет.
...
Рейтинг: 0 / 0
04.03.2002, 09:38
    #32024282
KonstN
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс по нескольким полям
Составной индекс может использоваться оптимизатором при поиску/сортировке по первому, или по первому и второму, или по первому и второму и третьему и т.д. и только так (не по второму, и не по второму и третьему), а для сортировки и только в таком порядке - например, если будет сортировка по второму, а потом первому, то этот индекс использоваться не будет.
С другой стороны, составной (он же покрывающий ) индекс может значительно(!) ускорить выборку, если в селект-листе запроса будут использоваться только поля, перечисленные в индексе. В этом случае не будут использоваться страницы данных, а только страницы индекса, что уменьшает план на один поиск по кластерному индексу или RID. Так что для часто выполняющихся запросов с небольшим количеством полей имеет смысл сделать покрывающий индекс со всеми полями, но с первым из них, по которому делается поиск.
Более того, есть один хинт - если часто делаются длинные цепочки из joinов, то есть резон делать индексы на внешних ключах не из них самих, а из них+первичный ключ. В этом случае цепочки начинают летать как отвязанные. А оверхед небольшой, потому что первичный ключ, как правило, четыре байта.
...
Рейтинг: 0 / 0
04.03.2002, 13:06
    #32024302
MadDog
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс по нескольким полям
2 KonstN:
Когда я написал "прошу повторить что-либо подобное" я имел в виду не прописные истины из книг "за 21 день", я просил повторить мои выборки на своих таблицах тех, у кого есть компьютер , с установленным sql2k.

Что же касается "покрывающих" индексов, я хорошо о них осведомлен, именно поэтому в моих запросах выбираются все поля. Обратите внимание на символ "*".
...
Рейтинг: 0 / 0
04.03.2002, 13:53
    #32024304
KonstN
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс по нескольким полям
2 MadDog
Я не стал ничего объяснять в приведённом Вами примере, потому что всё объяснил qu-qu.
Однако, если Вы настаиваете, скажу так - я написал вещи, которые будут работать всегда и отвечают на вопрос, заданный в теме.
Ваш же пример абсолютно ничего не говорит.
Он говорит только лишь о том, что иногда оптимизатор может выбрать использование индекса из-за того, что индексная страница меньше, чем страница данных, и scan пройдёт быстрее по ним. Но это не только нестандартное использование индекса, которое может и замедлить выполнение запроса (и иногда придётся делать хинты оптимизатору, чтобы заставить отказаться от неправильного плана), потому что не надо забывать о дополнительной операции по ссылке на кластерный индекс. Более того, этот план может выбираться или не выбираться от статистики - если индекс будет сильно не селективен, Вы всё равно его сделаете? - то есть получается, что сейчас индекс стОит строить, а через 5 минут нет, а потом опять стОит?
Таким образом, в общем случае ответ на первый вопрос - не по любому из полей.
Или Вы не согласны? Тогда почитайте ещё книги "за 21 день", там иногда толковые вещи пишут.

А насчёт asc/desc для DennisL - это используется для сортировки, но не для поиска.
...
Рейтинг: 0 / 0
05.03.2002, 06:54
    #32024350
KonstN
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс по нескольким полям
2DennisL
добавление - совсем забыл: asc/desc индексы ещё могут использоваться при поиске MIN/MAX.
Очень интересно посмотреть план например такого запроса
select * from ttt where fff in (select top 1 fff from ttt order by ааа desc)
...
Рейтинг: 0 / 0
05.03.2002, 07:40
    #32024355
Дмитрий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс по нескольким полям
Оффтопик, конечно. И, тем не менее, в большинстве отечественных форумов прослеживается тенденция унизить и оскорбить собеседника. Почему? Почему на Западе (например, на форуме www.sqlmag.com) Вам ответят, не обидев и не унизив, в то время как у нас тут обязательно это сделают. Даже если ты прав. Короче говоря, необходимо запретить ПОСТ некоторым господам.
...
Рейтинг: 0 / 0
05.03.2002, 07:48
    #32024359
qwerty
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс по нескольким полям
2Дмитрий
Здесь хороший форум. Не верите, загляните на линуксовый, особенно на обсуждение чего-либо.
Почувствуйте разницу
...
Рейтинг: 0 / 0
05.03.2002, 08:08
    #32024365
KonstN
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Индекс по нескольким полям
Ещё зайдите на IRC ))
Например, на #fidorus.
Это стиль жизни такой.
Ничего не попишешь, и банами здесь не помочь.
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Индекс по нескольким полям / 16 сообщений из 16, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]