Вторичный индекс InnoDB содержит значение вместо указателя на PK, как этого достаточно? - PullRequest
1 голос
/ 15 июня 2019

Я читаю Effective Mysql - Optimizing Mysql Statements и в chapter 3 было такое объяснение:

Вторичные индексы в InnoDB используют структуру данных B-дерева;однако они отличаются от реализации MyISAM. В InnoDB вторичный индекс хранит физическое значение первичного ключа. В MyISAM вторичный индекс хранит указатель на данные, содержащие значение первичного ключа.

Это важно длядве причины.Во-первых, размер вторичных индексов в InnoDB может быть намного больше, когда определен большой первичный ключ, например, когда ваш первичный ключ в InnoDB имеет длину 40 байт.По мере увеличения числа вторичных индексов размер сравнения индексов может стать значительным.Второе отличие состоит в том, что вторичный индекс теперь включает значение первичного ключа, и не является частью индекса. Это может быть значительным улучшением производительности при объединении таблиц и индексах покрытия.

Мне приходит в голову много вопросов, в основном из-за непонимания того, что автор пытается передать.

  1. Неясно, что автор имеет в виду во втором разнице во втором абзаце.Что больше не требуется как часть индекса ?

  2. Сохраняет ли B-дерево вторичного индекса InnoDB только значение PK или значение PK и указательк этому?или PK Value и указатель на строку данных?

  3. Какое улучшение производительности могло бы быть связано с методом хранения (ответ на второй вопрос)?

Это Вопрос содержит пример, а также ответ.Он объясняет, как оно содержит значение PK, но я до сих пор не понимаю:

Чтобы завершить объединение, если указатель отсутствует во вторичном индексе и есть только значение, MySQL не выполнит полное сканирование индексапо индексу первичного ключа с этим значением из вторичного индекса?Как это будет эффективнее, чем указатель?

Ответы [ 2 ]

2 голосов
/ 18 июня 2019

Основы ..

ПЕРВИЧНЫЙ КЛЮЧ MyISAM и вторичные ключи работают одинаково. - Оба являются BTrees в файле .MYI, где «указатель» в листовом узле указывает на файл .MYD.

«Указатель» - это либо смещение байта в файле .MYD, либо номер записи (для FIXED). Либо приводит к «поиску» в файле .MYD.

Данные InnoDB, включая столбцы PRIMARY KEY, хранятся в одном BTree, заказанном PK.

Это делает поиск ПК немного быстрее. Оба просматривают BTree, но MyISAM нужен дополнительный поиск.

Каждый вторичный ключ InnoDB хранится в отдельном BTree. Но в этом случае листовые узлы содержат дополнительные столбцы PK. Итак, поиск вторичного ключа сначала детализирует это BTree на основе вторичного ключа. Там он найдет все столбцы как вторичного ключа, так и первичного ключа. Если - это все нужные вам столбцы, это «индекс покрытия» для запроса, и больше ничего не делается. (Быстрее, чем MyISAM.)

Но обычно вам нужны другие столбцы, поэтому столбцы столбца PK используются для детализации данных / PK BTree, чтобы найти остальные столбцы в строке. (Медленнее, чем MyISAM.)

Итак, есть некоторые случаи, когда MyISAM выполняет меньше работы; некоторые случаи, когда InnoDB выполняет меньше работы. Там происходит много других вещей; InnoDB побеждает во многих сравнительных тестах над MyISAM.

Кэширование ...

MyISAM управляет кэшированием блоков индекса размером 1 КБ в key_buffer. Блоки данных кэшируются операционной системой.

InnoDB кэширует как блоки данных, так и вторичные индексы (16 КБ в обоих случаях) в buffer_pool.

«Кэширование» относится к замене блоков ввода / вывода по мере необходимости с использованием алгоритма «наименее недавно использованного».

BTree не загружен в RAM. Нет BTree явно хранится в оперативной памяти. Каждый блок запрашивается по мере необходимости, с надеждой , что он кэшируется в ОЗУ. Для данных и / или индексов, которые меньше соответствующего буфера (key_buffer / buffer_pool), BTree может случиться, что останется в ОЗУ до завершения работы.

Источник истины находится на диске. (Хорошо, есть сложные приемы, которые InnoDB использует с файлами журналов, чтобы избежать потери данных, когда происходит сбой до сброса блоков на диск. Эта очистка автоматически происходит при перезапуске после сбоя.)

Потянув за вилку ..

MyISAM:
Беспорядок № 1: Индексы останутся в нечистом состоянии. CHECK TABLE и REPAIR TABLE необходимы.
Беспорядок # 2: Если вы находитесь в середине UPDATEing тысячи строк в одном выражении, некоторые будут обновлены, некоторые - нет.

InnoDB:
Как упомянуто выше, InnoDB выполняет действия атомарно , даже при потягивании штекера. Ни один индекс не остался поврежденным. Нет UPDATE оставлено недоделанным; это будет ROLLBACKed.

Пример ..

Учитывая

columns a,b,c,d,e,f,g
PRIMARY KEY(a,b,c)
INDEX(c,d)

Листовые узлы BTree будут содержать:

MyISAM:
для ПК: a,b,c,pointer
для среднего: c,d,pointer

InnoDB:
для ПК: a,b,c,d,e,f,g (вся строка хранится в ПК)
для среднего: c,d,a,b

1 голос
/ 15 июня 2019

Вторичный индекс - это косвенный способ доступа к данным.В отличие от первичного (кластеризованного) индекса, когда вы пересекаете вторичный индекс в InnoDB и достигаете конечного узла, вы обнаруживаете первичный ключ значение для соответствующей строки, которую ищет запрос.Используя это значение, вы пересекаете первичный индекс для извлечения строки.Это означает, что поиск по индексу 2 в InnoDB .
Для MyISAM, поскольку лист вторичного узла является указателем на фактическую строку, вам требуется только поиск по одному индексу.

Вторичный индексформируется на основе определенных атрибутов вашей таблицы, которые не являются PK.Следовательно, PK не обязательно должен быть частью индекса по определению.Является ли это (InnoDB) или нет (MyISAM) - это детали реализации с соответствующими последствиями для производительности.
Теперь подход, который следует InnoDB, может сначала показаться неэффективным по сравнению с MyISAM (2 поиска против 1 поиска), но это не потому, чтопервичный индекс хранится в памяти, поэтому штраф невысок.
Но преимущество заключается в том, что InnoDB может разбивать и перемещать строки для оптимизации макета таблицы при вставке / обновлении / удалении строк без необходимости каких-либо обновлений вторичного индекса, посколькуон не ссылается на затронутые строки напрямую

...