Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 вопрос про индексы  [new]
Barr
Member

Откуда:
Сообщений: 11
Извините за ламерский вопрос но я хотел бы узнать какая разница если создать индекс для какждого поля отдельно или индекс с несколькими полями в одном. Как при этом работает MSSQL.
6 окт 04, 13:43    [1012570]     Ответить | Цитировать Сообщить модератору
 Re: вопрос про индексы  [new]
fima
Member

Откуда: Москва
Сообщений: 583
советую воспользоваться поиском, так как тема большая, для начала почитать здесь
6 окт 04, 14:09    [1012762]     Ответить | Цитировать Сообщить модератору
 Re: вопрос про индексы  [new]
Makar4ik
Member

Откуда: Когда-то были Лужки, а теперь Бордюр-Сити.
Сообщений: 2676
По разному.

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

т.е. при запросе типа

select * from sysobjects where xtype = 'S' and parent_obj = 0

сервер будет очень доволен, если найдет индекс по xtype и parent_obj.
И менее доволен, если найдет 2 штуки: xtype и parent_obj...
6 окт 04, 14:09    [1012767]     Ответить | Цитировать Сообщить модератору
 Re: вопрос про индексы  [new]
Barr
Member

Откуда:
Сообщений: 11
2 Makar4ik

А если запрос будет таким

select * from sysobjects where xtype = 'S' and info = 56

при индексе по xtype и parent_obj
6 окт 04, 14:24    [1012859]     Ответить | Цитировать Сообщить модератору
 Re: вопрос про индексы  [new]
Makar4ik
Member

Откуда: Когда-то были Лужки, а теперь Бордюр-Сити.
Сообщений: 2676
Barr
2 Makar4ik

А если запрос будет таким

select * from sysobjects where xtype = 'S' and info = 56

при индексе по xtype и parent_obj


Дык, смоделируй! =)
6 окт 04, 14:26    [1012872]     Ответить | Цитировать Сообщить модератору
 Re: вопрос про индексы  [new]
Алексей2003
Member

Откуда: Москва
Сообщений: 5645
разница... разница такая...
есть у вас 3 полок, в 1ой книги, 2ой тетрадки, 3ей учебные пособия
также 3 предмета (в каждой полке может быть) математика, физика, русский

надо выбрать тетрадки по математике
индексы по каждому полю в отдельности будут
для сервера тут 4 варианта
сканирование, использовать один индекс или 2 индекса
  • не использовать индекс
  • если один по полке, то выбирается нужная запись в полке и сканируются все тетрадки
  • если один по предмету, выбираются все что связано с математикой и сканируются полки
  • если 2 индекса выбираются нужная полка и нужный предмет по пред алгоритмам одновременно и потом эти записи сравниваются между собой.

    теперь если индекс по двум полям
    будет поиск по индексу сначала полка, потом предмет.

    при наличие доп.условий смари те 4 варианта.

    P.S. очень важно четко определить, что от последовательности перечисленных полей в индексе очень многое зависит.

    для спящего время бодрствования равносильно сну
  • 6 окт 04, 14:50    [1012992]     Ответить | Цитировать Сообщить модератору
     Re: вопрос про индексы  [new]
    Barr
    Member

    Откуда:
    Сообщений: 11
    2 Makar4ik
    Я хочу спросить как быстрее будет работать мой запрос, когда будет индекс по xtype и parent_obj или же два индекса xtype и parent_obj по отдельности. Просто у меня есть не индексированная таблица на которм свыше 25000000 записей. Я хочу его проиндексировать. Экспериментировать и играться не могу т.к. на индексацию уходит много времени чего у меня очень мало.
    6 окт 04, 14:51    [1013000]     Ответить | Цитировать Сообщить модератору
     Re: вопрос про индексы  [new]
    Jem
    Member

    Откуда:
    Сообщений: 735
    2 Алексей2003
    автор
    если 2 индекса выбираются нужная полка и нужный предмет по пред алгоритмам одновременно

    При этом сканирование описанное в пред. алгоритмах сохраняется?
    То есть это медленнее рабоает, я правильно понял?
    6 окт 04, 14:58    [1013038]     Ответить | Цитировать Сообщить модератору
     Re: вопрос про индексы  [new]
    Алексей2003
    Member

    Откуда: Москва
    Сообщений: 5645
    если делаются выборки
    по полю type или type и parent_obj, а по полю parent_obj отдельно не делается выборка, тогда индекса type и parent_obj хватит и ничего больше не нужно.
    если же по полю parent_obj делается выборка, тогда нужно смотреть что происходит чаще... возможно стоит создать 2 индекса
    по type и parent_obj и по parent_obj

    для спящего время бодрствования равносильно сну
    6 окт 04, 14:59    [1013043]     Ответить | Цитировать Сообщить модератору
     Re: вопрос про индексы  [new]
    Алексей2003
    Member

    Откуда: Москва
    Сообщений: 5645
    2Jem
    сканирование не сохраняется... получаются как бы 2 выборки, в которых сервер знает, что выбрались именно эти записи и делает join по этим двум выборкам, это работает медленнее чем если индекс по 2м полям но иногда быстрее чем по какому либо индексу в отдельности.

    для спящего время бодрствования равносильно сну
    6 окт 04, 15:01    [1013059]     Ответить | Цитировать Сообщить модератору
     Re: вопрос про индексы  [new]
    Barr
    Member

    Откуда:
    Сообщений: 11
    Я лишь хочу узнать если сделать один индекс по полям поле1, поле2, поле5, поле8, а запрос дам например по полям 1, 5, 7, 8 это будет быстреее чем отдельный индекс по отдельным полям. Возможно будут запросы по остальным полям тоже, пока не знаю. Если разница между первым и вторым случаем не большая то это даже не очень важно. Просто я выбираю из БОЛЬШОЙ таблицы, но не на сайт или программу какую-то, а просто создаю спарвку по нескольким месяцам. Мне не нужем мнговенный результат. Главное чтобы очень долго не работало.
    6 окт 04, 16:44    [1013665]     Ответить | Цитировать Сообщить модератору
     Re: вопрос про индексы  [new]
    Алексей2003
    Member

    Откуда: Москва
    Сообщений: 5645
    поле1, поле2, поле5, поле8, а запрос дам например по полям 1, 5, 7, 8
    индекс будет по полю поле1 по остальным будет скан.
    если запрос по полям 1, 2, 7, 8 тогда по: поле1, поле2

    для спящего время бодрствования равносильно сну
    6 окт 04, 16:47    [1013680]     Ответить | Цитировать Сообщить модератору
     Re: вопрос про индексы  [new]
    Makar4ik
    Member

    Откуда: Когда-то были Лужки, а теперь Бордюр-Сити.
    Сообщений: 2676
    Barr
    Я хочу спросить как быстрее будет работать мой запрос, когда будет индекс по xtype и parent_obj или же два индекса xtype и parent_obj по отдельности. Просто у меня есть не индексированная таблица на которм свыше 25000000 записей. Я хочу его проиндексировать. Экспериментировать и играться не могу т.к. на индексацию уходит много времени чего у меня очень мало.


    Все зависит от того, какие запросы будут превалировать.
    В общем случае, пока ясность с запросами нет, есть смысл пока ограниситься двумя мелкими индексами.
    Потом смотреть.
    Если не жалко места на диске, то можно сделать все три индекса.
    Сервер при запросах разберется, какие пользовать.
    6 окт 04, 16:51    [1013698]     Ответить | Цитировать Сообщить модератору
     Re: вопрос про индексы  [new]
    Gena G.
    Member

    Откуда: Oz
    Сообщений: 977
    Barr
    Я лишь хочу узнать если сделать один индекс по полям поле1, поле2, поле5, поле8, а запрос дам например по полям 1, 5, 7, 8 это будет быстреее чем отдельный индекс по отдельным полям. Возможно будут запросы по остальным полям тоже, пока не знаю. Если разница между первым и вторым случаем не большая то это даже не очень важно. Просто я выбираю из БОЛЬШОЙ таблицы, но не на сайт или программу какую-то, а просто создаю спарвку по нескольким месяцам. Мне не нужем мнговенный результат. Главное чтобы очень долго не работало.


    Если ты думаешь что можно что-то сделать хорошо обладая в этом вопросе поверхностными знаниями, то я тебе искреенне завидую. На статью, которая дает ответы на все твои вопросы, тебе указали. Осталось прочитать и сделать так как там рекомендуется. Еще, учитывая нешуточные размеры базы, рекомендую поискать в BOL алгоритм просчета размера индекса что бы иметь представление о том как будет выглядеть его размер для одного поля или для нескольких полей. Отсюда предположить сколько reads и главное writes будет иметь SELECT и INSERT/UPDATE для данной таблицы. И как это будет согласоваться с business rules данного приложения. Ну и так далее :)
    7 окт 04, 02:54    [1014496]     Ответить | Цитировать Сообщить модератору
     Re: вопрос про индексы  [new]
    AntZ
    Member

    Откуда:
    Сообщений: 14
    Рекомендую пару webcasts с МSDN по индексам
    http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032254503&Culture=en-US
    и
    http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032256511&Culture=en-US
    7 окт 04, 03:13    [1014500]     Ответить | Цитировать Сообщить модератору
     Re: вопрос про индексы  [new]
    Barr
    Member

    Откуда:
    Сообщений: 11
    Извините за столь долгое отсутствие и спасибо за помощь.
    Данную статью от fima прочитал. Узнал много интересного. Статьи от AntZ еще не прочитал но постараюсь перервести и прочитать. Задача немоного упрастилась и соответсвенно запрос тоже. Сделал один индекс где есть три поля которые я использую и FillFactor = 80%
    Вот запрос
    SELECT KR_TEL / 100000 AS RAY_KOD, RAY_ADI,
    -------------------SUMS---------------------
    SUM(KR_SUMMA) AS SUM_MAN_ALL,
    SUM(CASE WHEN ZONA = 1 THEN KR_DLIT  ELSE 0 END) AS DLIT_Z1,
    SUM(CASE WHEN ZONA = 1 THEN KR_SUMMA ELSE 0 END) AS SUM_Z1,
    SUM(CASE WHEN ZONA = 2 THEN KR_DLIT  ELSE 0 END) AS DLIT_Z2,
    SUM(CASE WHEN ZONA = 2 THEN KR_SUMMA ELSE 0 END) AS SUM_Z2,
    SUM(CASE WHEN ZONA = 3 THEN KR_DLIT  ELSE 0 END) AS DLIT_Z3,
    SUM(CASE WHEN ZONA = 3 THEN KR_SUMMA ELSE 0 END) AS SUM_Z3,
    SUM(CASE WHEN ZONA = 4 THEN KR_DLIT  ELSE 0 END) AS DLIT_Z4,
    SUM(CASE WHEN ZONA = 4 THEN KR_SUMMA ELSE 0 END) AS SUM_Z4,
    SUM(CASE WHEN KG = 882 OR KG BETWEEN 870 AND 875 THEN KR_DLIT  ELSE 0 END) AS DLIT_Z5,
    SUM(CASE WHEN KG = 882 OR KG BETWEEN 870 AND 875 THEN KR_SUMMA ELSE 0 END) AS SUM_Z5
    --------------------------------------------
    FROM KREDIT LEFT JOIN RAYON ON RAY_KOD = CAST(KR_TEL / 100000 AS INT) + 34200
                LEFT JOIN KG_ZONA ON KR_KG = KG
    WHERE
          KR_TEL BETWEEN 2500000 AND 3009999
      AND KR_GOD = 2004 AND KR_MES = 09
    GROUP BY KR_TEL / 100000, RAY_ADI
    
    Но почему-то SQL все равно делает сканирование таблицы. Я хочу это выяснить. На статье которую дал мне fima было написано (12. Распределение статистики)
    статья

    1.6842016E-3
    - средняя плотность распределения примерно 0.17%

    у меня 1.9841532E-6. Сколько процентов у меня. Как это считается. У меня 0.2% ?
    8 окт 04, 11:24    [1018351]     Ответить | Цитировать Сообщить модератору
     Re: вопрос про индексы  [new]
    Алексей2003
    Member

    Откуда: Москва
    Сообщений: 5645
    по поводу не использования индекса... индекс по колонке не используется, если эта колонка указана как параметр функции или учавствует в вычислении...
    в опщем вот эту конструкцию нужно заменить
    (KR_TEL / 100000 AS INT) + 34200
    на
    KR_TEL

    а план выполнения что показывает?
    set showplan_text on|off


    для спящего время бодрствования равносильно сну
    8 окт 04, 11:44    [1018485]     Ответить | Цитировать Сообщить модератору
     Re: вопрос про индексы  [new]
    Barr
    Member

    Откуда:
    Сообщений: 11
    SELECT KR_TEL / 100000 AS RAY_KOD, RAY_ADI,  -------------------SUMS---------------------  SUM(KR_SUMMA) AS SUM_MAN_ALL,  SUM(CASE WHEN ZONA = 1 THEN KR_DLIT  ELSE 0 END) AS DLIT_Z1,  SUM(CASE WHEN ZONA = 1 THEN KR_SUMMA ELSE 0 END) AS SUM_Z1,  
    
    
      |--Parallelism(Gather Streams, ORDER BY:([Expr1006] ASC))
           |--Sort(ORDER BY:([Expr1006] ASC))
                |--Hash Match(Aggregate, HASH:([Expr1006], [RAYON].[RAY_ADI]), RESIDUAL:([Expr1006]=[Expr1006] AND [RAYON].[RAY_ADI]=[RAYON].[RAY_ADI]) DEFINE:([Expr1007]=SUM([partialagg1022]), [Expr1008]=SUM([partialagg1023]), [Expr1009]=SUM([partialagg1024])
                     |--Parallelism(Repartition Streams, PARTITION COLUMNS:([Expr1006], [RAYON].[RAY_ADI]))
                          |--Hash Match(Partial Aggregate, HASH:([Expr1006], [RAYON].[RAY_ADI]), RESIDUAL:([Expr1006]=[Expr1006] AND [RAYON].[RAY_ADI]=[RAYON].[RAY_ADI]) DEFINE:([partialagg1022]=SUM([KREDIT].[kr_summa]), [partialagg1023]=SUM(If ([kg_zona].[zon
                               |--Compute Scalar(DEFINE:([Expr1006]=[KREDIT].[kr_tel]/100000))
                                    |--Hash Match(Right Outer Join, HASH:([kg_zona].[kg])=([Expr1020]), RESIDUAL:([Expr1020]=[kg_zona].[kg]))
                                         |--Parallelism(Distribute Streams, PARTITION COLUMNS:([kg_zona].[kg]))
                                         |    |--Clustered Index Scan(OBJECT:([UnixData].[dbo].[kg_zona].[PK_kg_zona]))
                                         |--Parallelism(Repartition Streams, PARTITION COLUMNS:([Expr1020]))
                                              |--Compute Scalar(DEFINE:([Expr1020]=Convert([KREDIT].[kr_kg])))
                                                   |--Hash Match(Right Outer Join, HASH:([RAYON].[RAY_KOD])=([Expr1021]), RESIDUAL:([RAYON].[RAY_KOD]=[Expr1021]))
                                                        |--Parallelism(Repartition Streams, PARTITION COLUMNS:([RAYON].[RAY_KOD]))
                                                        |    |--Index Scan(OBJECT:([UnixData].[dbo].[RAYON].[IX_ADI]))
                                                        |--Parallelism(Repartition Streams, PARTITION COLUMNS:([Expr1021]))
                                                             |--Compute Scalar(DEFINE:([Expr1021]=[KREDIT].[kr_tel]/100000+34200))
                                                                  |--Table Scan(OBJECT:([UnixData].[dbo].[KREDIT]), WHERE:((([KREDIT].[kr_tel]>=2500000 AND [KREDIT].[kr_tel]<=3009999) AND [KREDIT].[kr_god]=2004) AND [KREDIT].[kr_mes]=9))
    
    
    
    SET STATISTICS PROFILE OFF

    Я тут ничего не понимаю. Как это читать.

    Алексей2003
    по поводу не использования индекса... индекс по колонке не используется, если эта колонка указана как параметр функции или учавствует в вычислении...
    в опщем вот эту конструкцию нужно заменить
    (KR_TEL / 100000 AS INT) + 34200
    на
    KR_TEL

    А как тогда это сделать? Ведь мне нужны первые два знака. Я использую KR_TEL / 100000 не только здесь но около селекта и группировки. В этих случаях тоже индексы не используются или только там где вы сказали?

    P.S. Я заменил CAST(KR_TEL / 100000 AS INT) + 34200 на KR_TEL / 100000 + 34200. Это было ошибка. Зачем преобразовать поле int на int. И еще в конец добавил ORDER BY RAY_KOD
    8 окт 04, 13:35    [1019120]     Ответить | Цитировать Сообщить модератору
     Re: вопрос про индексы  [new]
    Алексей2003
    Member

    Откуда: Москва
    Сообщений: 5645
    select * FROM KREDIT
     WHERE
          KR_TEL BETWEEN 2500000 AND 3009999
      AND KR_GOD = 2004 AND KR_MES = 09
    а этот запрос использует индекс?

    А как тогда это сделать?
    вычисляемая колонка и по ней индекс.


    для спящего время бодрствования равносильно сну
    8 окт 04, 16:06    [1019892]     Ответить | Цитировать Сообщить модератору
     Re: вопрос про индексы  [new]
    Алексей2003
    Member

    Откуда: Москва
    Сообщений: 5645
    около селекта и группировки не важно... важно то что на те самые 25000000 идет джоин вместе со сканом таблицы. когда вы отберете и в group by уже попадет строк поменьше, и времени будет занимать тоже меньше, так что в селекте и group by это использовать в принципе можно.

    P.S. когда сделаете вычисляемую колонку, используйте в джоине именно ее, а не тоже вычисление, только тогда будет использоваться индекс.

    для спящего время бодрствования равносильно сну
    8 окт 04, 16:08    [1019908]     Ответить | Цитировать Сообщить модератору
     Re: вопрос про индексы  [new]
    Barr
    Member

    Откуда:
    Сообщений: 11
    Алексей2003
    select * FROM KREDIT
     WHERE
          KR_TEL BETWEEN 2500000 AND 3009999
      AND KR_GOD = 2004 AND KR_MES = 09
    а этот запрос использует индекс?
    А почему не пойдет? Ведь все поля которые здесь входят в один индекс. Один единственный индекс и состоит тз этих трех полей.

    Вычесляемое поле?... Попробую...
    8 окт 04, 17:42    [1020416]     Ответить | Цитировать Сообщить модератору
     Re: вопрос про индексы  [new]
    Barr
    Member

    Откуда:
    Сообщений: 11
    Алексей2003
    select * FROM KREDIT
     WHERE
          KR_TEL BETWEEN 2500000 AND 3009999
      AND KR_GOD = 2004 AND KR_MES = 09
    а этот запрос использует индекс?
    А почему не использует? Ведь все поля которые здесь, входят в один индекс. Один единственный индекс и состоит из этих трех полей.

    Вычесляемое поле?... Попробую...

    P.S. Кстати как на этом форуме исправить ошибки поста?
    8 окт 04, 17:45    [1020427]     Ответить | Цитировать Сообщить модератору
     Re: вопрос про индексы  [new]
    Glory
    Member

    Откуда:
    Сообщений: 104764
    А почему не использует? Ведь все поля которые здесь, входят в один индекс. Один единственный индекс и состоит из этих трех полей
    select * потребует еще обращения и к самой таблице. Поэтому не факт что использование индекса будет быстрее
    8 окт 04, 19:20    [1020636]     Ответить | Цитировать Сообщить модератору
    Все форумы / Microsoft SQL Server Ответить