Имеет ли смысл использовать индекс, который будет иметь низкую мощность? - PullRequest
37 голосов
/ 22 января 2010

Я в основном разработчик Actionscript и никоим образом не эксперт в SQL, но время от времени мне приходится разрабатывать простые вещи на стороне сервера. Поэтому я решил спросить более опытных людей о вопросе в заголовке.

Насколько я понимаю, вы мало что получаете, устанавливая индекс в столбце, который будет содержать несколько различных значений. У меня есть столбец, который содержит логическое значение (на самом деле это маленький int, но я использую его как флаг), и этот столбец используется в предложениях WHERE большинства запросов, которые у меня есть. В теоретическом «среднем» случае половина значений записей будет равна 1, а другая половина - 0. Таким образом, в этом сценарии ядро ​​базы данных может избежать полного сканирования таблицы, но в любом случае придется читать много строк (всего строк / 2).

Итак, я должен сделать этот столбец индексом?

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

Заранее спасибо.

Ответы [ 4 ]

69 голосов
/ 22 января 2010

Индекс может помочь даже в полях с низким количеством элементов, если:

  1. Когда одно из возможных значений является очень редким по сравнению с другими значениями, и вы ищете его.

    Например, очень мало дальтоников, поэтому этот запрос:

    SELECT  *
    FROM    color_blind_people
    WHERE   gender = 'F'
    

    наиболее вероятно выиграет от индекса на gender.

  2. Когда значения имеют тенденцию группироваться в табличном порядке:

    SELECT  *
    FROM    records_from_2008
    WHERE   year = 2010
    LIMIT 1
    

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

  3. Когда вам нужно ORDER BY / LIMIT:

    SELECT  *
    FROM    people
    ORDER BY
            gender, id
    LIMIT 1
    

    Без индекса потребуется filesort. Несмотря на то, что он несколько оптимизирован для LIMIT, для него все равно потребуется полное сканирование таблицы.

  4. Когда индекс охватывает все поля, используемые в запросе:

    CREATE INDEX (low_cardinality_record, value)
    
    SELECT  SUM(value)
    FROM    mytable
    WHERE   low_cardinality_record = 3
    
  5. Когда вам нужно DISTINCT:

    SELECT  DISTINCT color
    FROM    tshirts
    

    MySQL будет использовать INDEX FOR GROUP-BY, и если у вас мало цветов, этот запрос будет мгновенным даже с миллионами записей.

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

Обратите внимание, что если производительность DML невелика, создать индекс безопасно.

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

9 голосов
/ 22 января 2010

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

SELECT ... FROM Messages WHERE Deleted = 0 AND Date BETWEEN @start AND @end

Вам определенно будет полезно иметь составной индекс для полей Удалено и Дата .

3 голосов
/ 22 января 2010

Я обычно делаю простой тест «есть индекс» против «нет» индекса. По моему опыту, вы получаете большую производительность по запросам, которые используют ORDER BY в индексированном столбце. Если у вас есть какая-либо сортировка по этому столбцу, индексация, скорее всего, поможет.

2 голосов
/ 22 января 2010

ИМХО это ограниченная полезность.Я предполагаю, что в большинстве случаев есть другие критерии, которые вы используете в своих запросах в дополнение к флагу, которые, вероятно, помогут намного больше.

При 50%, я бы, вероятно, сделал несколько сравнительных тестов с / без и посмотрел, имеет ли это большое значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...