|
Строить индекс или нет
|
|||
---|---|---|---|
#18+
Привет Всем! В руководстве по SQL2000 не рекомендуют строить индекс для больших баз, если индексируемое поле содержит малое количество уникальных ключей (я примерно так перевел эту фразу). В качестве примера приведено поле, которое содержит пол человека - всего 2 уникальных значения. С этим все понятно - уж больно явный пример. А теперь вопрос из реальной жизни. Имеется таблица ~100 миллионов записей и в ней поле Category varchar(5).Количество уникальных значений ~10 (может быть вырастет до 20-30). В типовых запросах используется группировка по данному полю. ВОПРОС - строить ли индекс по этому полю или нет ? И может быть имеется какая-нибудь методика (хотя бы приблизительная) для оценки необходимости построения индекса ? ... |
|||
:
Нравится:
Не нравится:
|
|||
21.02.2001, 10:41 |
|
Строить индекс или нет
|
|||
---|---|---|---|
#18+
А Index Tuning Wizard что Вам советует? ... |
|||
:
Нравится:
Не нравится:
|
|||
21.02.2001, 10:54 |
|
Строить индекс или нет
|
|||
---|---|---|---|
#18+
Index Tuning Wizard ничего не может посоветовать т.к. индекс уже построен (до меня). Просто он занимает > 1Gb места на диске и в связи с прочитанным руководством возник этот вопрос. Если индекс не дает эффекта, то зачем зря растрачивать место на диске ? ... |
|||
:
Нравится:
Не нравится:
|
|||
21.02.2001, 11:30 |
|
Строить индекс или нет
|
|||
---|---|---|---|
#18+
Судя по всему фраза переведена неправильно, как я понимаю в ней имеется в виду, что не стоит строить индекс на полях с низкой селективностью, т. е. если запросы чаще всего возвращают большое количество записей и оптимизатор вычисляет, что дешевле выборку делать не по индексу а просто сканировать таблицу. Используется ли индекс, можно посмотреть в Query Analyzer включив показ плана выполнения запроса. А вот Index Tuning Wizard всегда может че нить полезное посоветовать, даже если и индекс уже построен. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.02.2001, 12:47 |
|
Строить индекс или нет
|
|||
---|---|---|---|
#18+
Присоеденяюсь к Genady, он меня опередил на секунду... ... |
|||
:
Нравится:
Не нравится:
|
|||
21.02.2001, 12:50 |
|
Строить индекс или нет
|
|||
---|---|---|---|
#18+
Да вот еще посмотрел на число уникальных значений (не ключей - разные вещи совершенно), то скорее всего индекс здесь действительно не нужен, но я бы все равно попроверял все зависит от запросов. Можно было бы попробовать кластерный, но при этом есть опасность и достаточно большая что операции insert, update будут выполняться невообразимо медленно. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.02.2001, 12:53 |
|
Строить индекс или нет
|
|||
---|---|---|---|
#18+
original text was "Columns Not to Index Do not index columns that: 1. You seldom reference in a query 2. Contain FEW UNIQUE VALUES.For example, an index on a column with two values, male and female, returns a high percentage of rows. ....." ... |
|||
:
Нравится:
Не нравится:
|
|||
21.02.2001, 13:20 |
|
Строить индекс или нет
|
|||
---|---|---|---|
#18+
Ну, так все верно Values - значений, Unique key это Primary key or Alter key. Индекс Вам скорее всего не нужен. Самая простая методика как я уже говорил, посмотреть по плану выполнения запроса используется ли он в типовых запросах. Если нет, то однозначно не нужен, он ничего не дает, ну а наоборот ессно нужен. ) Как я говорил ранее, нужно посмотреть тип индекса, если он некластерный и обновления происходят очень редко, то я думаю (не уверен, но попробовать можно) можно попробовать сделать этот индекс кластерным. В таком случае записи в таблице сортируются и скан будет производится проще и быстрее. Однако, если обновления часты и таблица, как я понял большая, то этот индекс просто убьет быстродействие по операциям insert and update. Удачи ) ... |
|||
:
Нравится:
Не нравится:
|
|||
21.02.2001, 13:57 |
|
Строить индекс или нет
|
|||
---|---|---|---|
#18+
Индекс из 30 разных значений на 100 миллионов можжно смело удалить. А уж делать его кластерным ... просто нет слов. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.02.2001, 17:38 |
|
Строить индекс или нет
|
|||
---|---|---|---|
#18+
>А уж делать его кластерным ... просто нет слов. Вобще то, было бы лучше, ели бы слова все таки нашлись, потому что откровенно говоря я не понимаю как Full table scan может быть быстрее clustered index scan. На всякий случай я еще раз повторюсь, что я говорю именно о select-ах. Да, вот небольшая цитата из Books online: Before creating clustered indexes, understand how your data will be accessed. Consider using a clustered index for: Columns that contain a limited number of distinct values, such as a state column that contains only 50 distinct state codes. However, if there are very few distinct values, such as only 1 and 0, no index should be created. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.02.2001, 10:11 |
|
Строить индекс или нет
|
|||
---|---|---|---|
#18+
Индекс по полю из секции Group By не нужен. Это понятно и без экспероиментов и без Index Tuning Wizard. Поправьте меня, если что-то не тек: Пусть есть таблица T из 10000 строк. Пусть для получения результата запроса А необходимо только 10 строк из таблицы T. При выполнении запроса, для поиска необходимых 10 строк, в худшем случае требуются фактически просмотреть все 10000 строк, а в лучшем только 10 строк. Условия из секции WHERE уменьшает необходимое кол-во строк (в моем примере 10). А индекс по полю из секции WHERE уменьшает фактическое кол-во просматриваемых строк ( в моем примере это может быть от 10000 до 10). ПОЛЯ ИЗ СЕКЦИИ Group By НИЧЕГО НЕ УМЕНЬШАЮТ: не необходимое кол-во строк и не фактичекое кол-во просматриваемых строк. Эти поля только влияют на форму представления результата. Например: Если в запросе нет секции WHERE, то просматриваются все строки таблицы. А если все равно просматриваются все строки, то зачем индекс. НЕ ВСЕ ЛИ РАВНО В КАКОЙ ПОСЛЕДОВАТЕЛЬЕОСТЬ ПРОСМОТРЕТЬ ВСЕ СТРОКИ!!! Full table scan или clustered index scan при просмотре всех строк таблицы работает одинаково Следовательно по полю из секции Group By индекс не нужен, если это поле не используется и в секции where. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.02.2001, 16:44 |
|
Строить индекс или нет
|
|||
---|---|---|---|
#18+
>Например: >Если в запросе нет секции WHERE, то просматриваются все строки таблицы. >А если все равно просматриваются все строки, то зачем индекс. >НЕ ВСЕ ЛИ РАВНО В КАКОЙ ПОСЛЕДОВАТЕЛЬЕОСТЬ ПРОСМОТРЕТЬ ВСЕ СТРОКИ!!! >Full table scan или clustered index scan при просмотре всех строк таблицы работает одинаково Не уверен, я провел маленький эксперимент (ну просто инетересно было) загнал в табличку из трех столбцов 1500000 записей в одном из столбцов было 3 уникальных значения. select-ы c group by при кластерном индексе на этом столбце отрабатывались даже визуально быстрее, чем без индекса. Я не знаю механизма выборки такого запроса, но как мне кажется индекс в данном случае даже очень помогает, и полагаю тому есть объяснение, поскольку группировать отсортированные строки должно быть легче. Завтра, если будет время я сделаю замеры (тоже просто интересно) Разумеется select по другим столбцам выполняется с одинаковой скоростью. (Замеры делал в Profiler-e, но вобщем на глазок, так что цифры не привожу) P.S. По поводу есть ли в типовых запросах выражение Where, Glory ничего не говорил, но как я понял, что если это выражение присутствует Вы согласны, что кластерный индекс может оказаться весьма полезным. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.02.2001, 17:32 |
|
Строить индекс или нет
|
|||
---|---|---|---|
#18+
Уважаемый VadimB, к сожалению теоретические рассуждения не всегда подтверждаются практикой пример: есть таблица транцакций: [transactions] достаточно широкая - запись занимает около 850 байт для нас актуально поле [type] таблица имеет несколько индексов, в том числе некластерный индекс по полю [type], и кластерный уникальный индекс по полям [tran_num], [type] мы делаем выборку: SELECT MAX([tran_num]), COUNT(*) 'count', [type] FROM [transactions] GROUP BY [type] а затем повторяем ее предварительно снеся с таблицы все индексы получаем результат: tran_num count type ---------------- ----------- -------- ZYZ87925 13079 101 ZYY9978-6214 6393 102 как ни странно в первом запросе сервер предпочитает использовать индекс по полю [type] а не уникальный кластерный индекс! при этом input output statistics для первого случая: Table 'transactions'. Scan count 1, logical reads 100, physical reads 0, read-ahead reads 94. а во втором: Table 'transactions'. Scan count 1, logical reads 961, physical reads 0, read-ahead reads 961. невооруженным глазом видно - во втором случае на порядок быстрее можно попробовать объяснить почему - зачем же читать всю таблицу, если основная обработка ведется по полю, входящему в индекс - а индекс-то значительно меньше самой таблицы конечно если в запросе будет вычисляться сумма... тогда совсем другое дело так что не надо про GROUP BY так категорично, а то научите человека плохому Index Tuning Wizard это то что нужно ... |
|||
:
Нравится:
Не нравится:
|
|||
22.02.2001, 17:33 |
|
Строить индекс или нет
|
|||
---|---|---|---|
#18+
Нда, так вот, сейчас на небольшой таблице проверил, схожие условия и вобщем все понятно: для агрегирования с кластерным индексом оптимизатор использует Stream Aggregate, который весит 32% запроса. А вот когда без индекса, тогда используется Hash Match/Aggregate, он то как раз весит 55% запроса. Так что, на выбор DBA Вопросы? ... |
|||
:
Нравится:
Не нравится:
|
|||
22.02.2001, 17:53 |
|
Строить индекс или нет
|
|||
---|---|---|---|
#18+
Вопросы есть 1) Genady Если Stream Aggregate весит 32%, а Match/Aggregate весит 55%, то это не значит, что реальное время выполнения запроса распределяется так-же. У меня очень часто в QA вес не соответствует времени. 2) Denis Вы написали: Scan count 1, logical reads 100, physical reads 0, read-ahead reads 94. Scan count 1, logical reads 961, physical reads 0, read-ahead reads 961. Вы хотите этим сказать, Что в одном случае надо прочитать меньше записей, чем в другом, т.е. все записи из таблицы считываются за разное число операций, в зависимости от индекса? Мне кажется такого не может быть или числа в Scan count 1, logical reads 961, physical reads 0, read-ahead reads 961 не имеют к этому никакого отношения. 3) Согласен, что для выполнения запрос типа select count(*) groyp by [Feled], когда имеется индекс по [Field], сама таблица не нужна, а используется индекс и следовательно мои предыдушие рассужнения не верны. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.02.2001, 18:43 |
|
Строить индекс или нет
|
|||
---|---|---|---|
#18+
Я смотрю обсуждение имеет больше теоритический характер, а мне хотелось бы практических советов. Поэтому дам более развернутую версию вопроса 1. Данные. База предназначена для статистических отчетов и поисков. Обновляется 1 раз в месяц большим куском (8-9 млн записей) Две основные таблицы - calls 102 млн записей, рост 8-9 млн в месяц id int identity - номер записи start datetime - начало звонка duration int - продолжительность client char(7) - код клиента ~110 000 уник.значения, рост 5-6 тыс в месяц telnumber varchar(10) - тел.номер клиента ~200000 уник.значения, рост 7-8 тыс в месяц dialled varchar(1 - набранный номер ??? уник.значения,рост ??? destination varchar(5) - код направления, 12 уник.значений category varchar(5) - категория звонка class varchar(5) - класс звонка break varchar(5) - период звонка 3 уник.значения, рост пока не предвидется inv_number char(10) - номер счета FK_invoices -invoices 1200 тыс.записей, рост 110-120тыс. в месяц inv_number char(10) - номер счета client varchar(7) - код клиента telnumber char(10) - тел.номер клиента inv_period datetime - отчетный период at_code varchar(5) - пакет услуг 2. Типовые запросы -Всегда присутствует период, но это может пониматься как calls.start так и invoices.inv_period Далее могут быть заданы/не заданы client, telnumber, dialled, destination, category, break, at_code как со всеми возможными вариантами группировок, так и без них 3.Мои соображения Пока они заканчиваются тем, что необходим кластерный индекс по calls.start(+ может быть еще что-то). В остальном пока мешанина из руководств и мнений. 4.Чего жду Какой-то план действий по выявлению оптимальных индексов, учитывая, что база уже активно используется и сносить/создавать индексы да еще на таком объеме хотелось бы ну если не с первого захода, то хотя бы с 3-го ... |
|||
:
Нравится:
Не нравится:
|
|||
22.02.2001, 19:05 |
|
Строить индекс или нет
|
|||
---|---|---|---|
#18+
Тут народ уже неоднократно советовал прибегнуть к помощи Index Tuning Wizard, и я поддерживаю эту идею. Суждения и оценки по поводу оптимальности / неоптимальности индексов - это прекрасно в качестве необходимой зарядки для ума и небольших задач. Для сложных вещей лучше использовать соотв-й инструмент. Конечно, таблицу умножения надо держать в уме, но для сложных вычислений проще все-таки взять калькулятор. Натравите ITW на свои типовые запросы (п.2) и он решит за Вас задачу "по выявлению оптимальных индексов", т.к. это инструмент, создававшийся специально для таких операций. Пусть Вас не смущает слово Wizard в его названии (как пр., с визардами привыкли ассоциировать не слишком замысловатые программы). В основе ITW лежит достаточно продвинутая аналитика, и конкуренты подобные вещи предлагают за отдельные деньги. Кстати, в след.версии его, наверное, все-таки переименуют, т.к. слово Wizard действительно misleading в данной ситуации. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.02.2001, 21:54 |
|
Строить индекс или нет
|
|||
---|---|---|---|
#18+
Для теоретических изыскателей: вкратце разъясню (только тем, кому это непонятно) каким образом оказывается при работе с индексом больше дисковых операций больше, чем без использования индекса. Когда неупорядоченные данные (ну в очень больших количествах) разбросаны по разным страницам, при доступе к ним с использованием индекса сервер может обратиться несколько раз к одной и той же странице данных (если просматривает их по индексу). Если объем данных большой, и все страницы не могут кэшироваться в памяти, может возникнуть необходимость считать одну и ту же страницу несколько раз . Дополнительные затраты вызывает чтение страниц индекса (если индекс не кластерный). В такой ситуации сканирование таблицы без использования индекса более выгодно - каждая страница данных читается с диска и используется однократно. Для практиков. В SQL-2000 появилась возможность разбить таблицу большой емкости по разным файлам базы данных - как раз в соответсвии с периодами, к которым эти данные относятся. Если чаще всего данные выбираются только за последний период, то оптимизатор запросов исключит обращение к частям таблицы, относящимся к древним учетным периодам. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.02.2001, 22:01 |
|
Строить индекс или нет
|
|||
---|---|---|---|
#18+
for VadimB не очень понял вашего ко мне вопроса, и был ли это вопрос на который требуется ответ? но если есть желание пообщаться я не против - мое мыло и аська есть в моем профиле... ... |
|||
:
Нравится:
Не нравится:
|
|||
23.02.2001, 00:51 |
|
Строить индекс или нет
|
|||
---|---|---|---|
#18+
for Glory: Целиком поддерживаю Деда Маздая - без исследования работы базы как минимум с помощью ITW Вам трудно будет что либо решить. Я в своих экспериментах использовал очень простой вариант, который может очень сильно отличатся от Вашего случая. К тем данным, которые Вы дали было бы неплохо описать на каких полях построен индекс, как я понимаю то самое поле из-за которого возникла дискуссия это destination. Да вот еще что, судя по тому что вы посмотрели размер индекса, наводит меня на подозрения, что он некластерный, т. к. размер кластерного индекса Enterprise Manager не показывает, потому что он есть отсортированная таблица с дополнительными страницами ветвей для индексированния. Поэтому он совершенно не нужен. Повторюсь еще раз, о том какой нужен, лучше всего спросить у ITW. for VadimB: Как я понимаю Вы все таки до конца не понимаете механизма выполнения запроса типа select sum(Field1), Field2 from table group by Field2 В данном случае sum для примера. Так вот выполнение запроса можно разделить (и потимизатор так и делает) на два этапа: 1. получение данных (скан всей таблицы и кластерного индекса будут практически одинаковы по времени) 2. применение агрегирования для полученных данных. Даже просто интуитивно можно понять, что для отсортированных записей операция будет выполняться быстрее. Применение hash функции, конечно хорошая вещь, но все таки более медленная, чем захват данных потоком. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.02.2001, 09:46 |
|
Строить индекс или нет
|
|||
---|---|---|---|
#18+
Правильно дедушка говорил, покрутите запросы в Index Tuning Wizard. Хотя Mocrosoft рекомендует не использовать индексы для полей с низкой селективностью, грань эта всегда остаётся размытой. Что бы ентот визард не сильно врал, нужно ему подсунуть более - менее реальную нагрузку, которая может быть создана в профайлере, при выполнении реального запроса. И, акромя того, можно использовать всякие подсказки, что бы посмотреть, как будет зависить скорость исполнения запроса от применения индекса или его не применения. А ещё, дедушка нам на ночь расказывал сказочку про то, что индексы бывают не только по одному полю, а ещё эти, как их..., а! СОСТАВНЫЕ, вот. Для анализа таких вот заковыристых вещей вам точно без ИТВ не обойтись. И ещё. С праздничков вас, дорогие наши дедушки, дяденьки и мальчики! 23 февраля 2000г. Тёмно-синий лес. Зайцы. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.02.2001, 10:19 |
|
Строить индекс или нет
|
|||
---|---|---|---|
#18+
Naschet ispolzovanija Index Tuning Wizard mne ponjatno. Vopros v sledujushem - chto litshe ili pravilnee - zapuskat zaprosy po ocheredi v Query Analyzer i srazu po ego okonchanii ITW - ili skazem cherez Profiler sozdat trace file, zapustit vse zaprosy i natravit potom ITW na trace file (togda kakie sobytija otslezivat v Profiler-e ?) ... |
|||
:
Нравится:
Не нравится:
|
|||
23.02.2001, 11:09 |
|
Строить индекс или нет
|
|||
---|---|---|---|
#18+
В теории по большому счету должно быть по барабану, в каком виде нагрузку ему подсовывать - в виде батча или трассы. Я стараюсь использовать трассу, елико это возможно, но объяснить свое пристрастие с материалистических позиций затрудняюсь. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.02.2001, 12:07 |
|
Строить индекс или нет
|
|||
---|---|---|---|
#18+
Рассуждаю теоретически, если не прав, не бейте. Думаю что трасса лучше, т. к. предполагаю, что ITW запрограммирован таким образом, чтобы учитывать в этом случае производительность всех запросов, а не какого либо одного. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.02.2001, 12:38 |
|
Строить индекс или нет
|
|||
---|---|---|---|
#18+
I eshe voprosy Udaljat-li dlja chistoty eksperimenta vse sushestvujushie indeksy ? I esli udaljat, to ne povlijaet-li posle etogo na resultaty ITW uporjadochivanie tablitsy iz-za predydushego klasternogo indeksa calls.start ? Ne pridetsja li mne prodelyvat vse eti operatsii zanovo posle dobavlenija ocherednoi portsii dannyh (smotri opisanie vyshe) ? ... |
|||
:
Нравится:
Не нравится:
|
|||
23.02.2001, 14:16 |
|
|
start [/forum/topic.php?fid=46&msg=32002487&tid=1827302]: |
0ms |
get settings: |
11ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
29ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
57ms |
get tp. blocked users: |
1ms |
others: | 14ms |
total: | 148ms |
0 / 0 |