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

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

PS sql2k. В 7.0 было немного по-другому, по-моему.
...
Рейтинг: 0 / 0
Индекс по нескольким полям
    #32023673
AlexSh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Думаю, что по первому столбцу индекса и по комбинации первого и второго оптимизация будет точно.
...
Рейтинг: 0 / 0
Индекс по нескольким полям
    #32023788
Фотография Garya
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexSh дал ответ, который звучал неуверенно, но в отличие от всех других был правильным.
Индекс по комбинации полей используется если в запросе перечислены первые поля индекса. Если какое-либо поле начиная от первого в запросе пропущено, индекс задействован не будет. Это во-первых.
Во-вторых, составной индекс использует больше места для хранения информации об одной записи (значения индексируемых полей). Следовательно, составной индекс, у которого задействовано в запросе только одно (первое поле), будет работать медленнее из-за перебора бОльшего количества страниц индекса, нежели при использовании индекса по одному полю.
Резюме. Составные индексы имеет смысл использовать только в тех случаях, когда запросы всегда строятся с использованием задействованной в индексе комбинации полей.
...
Рейтинг: 0 / 0
Индекс по нескольким полям
    #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
Индекс по нескольким полям
    #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
Индекс по нескольким полям
    #32024250
MadDog
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 qu-qu:
Тут где-то звучал афоризм, не помню чей - не удалось найти, "Читай внимательно и до конца". К этому остается только добавить - "Читай сначала".
Был вопрос:
"индекс по нескольким полям таблицы ... будет ускорять поиск по любому из полей[?]"
Прозвучал ответ:
Индекс по комбинации полей используется если в запросе перечислены первые поля индекса. Если какое-либо поле начиная от первого в запросе пропущено, индекс задействован не будет.
Я попытался показать что может быть использовано любое подходящее поле из составного индекса, в том числе не первое. Зависит это, как Вы правильно заметили, от "селективности". А уж как там этот индекс обрабатывается (scan или seek) - какая разница, если это быстрее чем table scan? Ведь вопрос (
"Читай сначала") звучал именно так: "будет ускорять"? Ответ - будет.
...
Рейтинг: 0 / 0
Индекс по нескольким полям
    #32024282
KonstN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Составной индекс может использоваться оптимизатором при поиску/сортировке по первому, или по первому и второму, или по первому и второму и третьему и т.д. и только так (не по второму, и не по второму и третьему), а для сортировки и только в таком порядке - например, если будет сортировка по второму, а потом первому, то этот индекс использоваться не будет.
С другой стороны, составной (он же покрывающий ) индекс может значительно(!) ускорить выборку, если в селект-листе запроса будут использоваться только поля, перечисленные в индексе. В этом случае не будут использоваться страницы данных, а только страницы индекса, что уменьшает план на один поиск по кластерному индексу или RID. Так что для часто выполняющихся запросов с небольшим количеством полей имеет смысл сделать покрывающий индекс со всеми полями, но с первым из них, по которому делается поиск.
Более того, есть один хинт - если часто делаются длинные цепочки из joinов, то есть резон делать индексы на внешних ключах не из них самих, а из них+первичный ключ. В этом случае цепочки начинают летать как отвязанные. А оверхед небольшой, потому что первичный ключ, как правило, четыре байта.
...
Рейтинг: 0 / 0
Индекс по нескольким полям
    #32024302
MadDog
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 KonstN:
Когда я написал "прошу повторить что-либо подобное" я имел в виду не прописные истины из книг "за 21 день", я просил повторить мои выборки на своих таблицах тех, у кого есть компьютер , с установленным sql2k.

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

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


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