Индекс мощности MySQL - производительность в сравнении с эффективностью хранения - PullRequest
20 голосов
/ 08 апреля 2010

Допустим, у вас есть таблица MyISAM MySQL 5.0 с 100 миллионами строк с одним индексом (кроме первичного ключа) для двух целочисленных столбцов.

Из моего, по общему признанию, плохого понимания структуры B-дерева я считаю, что меньшая мощность означает, что эффективность хранения индекса выше, поскольку родительских узлов меньше.Принимая во внимание, что более высокая кардинальность означает менее эффективное хранение, но более высокую read производительность, потому что ему приходится перемещаться по меньшему количеству ветвей, чтобы получить любые данные, которые он ищет, чтобы сузить строки дляquery.

(Примечание. Под "низким" по сравнению с "высоким" я не имею в виду, например, 1 миллион против 99 миллионов для таблицы строк на 100 миллионов. Я имею в виду больше как 90 миллионов против 95 миллионов)

Правильно ли мое понимание?

Смежный вопрос - Как кардинальность влияет на запись производительность?

1 Ответ

26 голосов
/ 08 апреля 2010

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

Большая мощность означает лучшую производительность чтения, потому что по определению меньше записей для чтения.

Чтобы обработать запрос следующим образом:

SELECT  *
FROM    mytable
WHERE   indexed_col = @myvalue

, двигатель должен выполнить следующие шаги:

  1. Найдите первую запись, удовлетворяющую условию.

    Это делается путем обхода B-Tree, начиная с корневой записи.

    По всем страницам поиск осуществляется по ссылкам B-Tree; на странице поиск выполняется с помощью бинарного поиска (если ваши ключи не сжаты, в этом случае это линейный поиск).

    Этот алгоритм одинаково эффективен как для столбцов с высокой, так и для низкой мощности. Нахождение первого 3 (в отличие от любого 3) в этих списках:

    1  2  3  4  5  6  7  8  9  10
    
    3  3  3  3  3  3  3  3  4  4
    

    требуется столько же O(log(n)) шагов.

  2. Обход индекса до изменения значения ключа. Это, конечно, требует линейного времени: чем больше у вас записей, тем больше вам нужно пройти.

Если вам нужна только первая запись:

SELECT  *
FROM    mytable
WHERE   indexed_col = @myvalue
LIMIT 1

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

Как кардинальность влияет на производительность записи?

Каждый индексный ключ имеет скрытое дополнительное значение: указатель записи. В этом весь смысл наличия индекса: вам нужно знать, на какую запись он указывает.

Поскольку указатель записи по определению уникален, каждый индексный ключ также уникален. Записи индекса, имеющие одно и то же значение ключа, сортируются по указателю записи.

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

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

Итак, ответ на ваши вопросы: нет, количество столбцов не влияет на производительность записи индекса.

...