Можно ли заставить InnoDB использовать индексы, аналогичные MyISAM, вместо кластерного индекса из-за ограничения оперативной памяти при одновременном использовании преимуществ ее производительности параллелизма?
Можно ли заставить InnoDB использовать индексы, аналогичные MyISAM, вместо кластерного индекса из-за ограничения оперативной памяти при одновременном использовании преимуществ ее производительности параллелизма?
Ответы:
Gen_clust_index (кластерный индекс) под капотом InnoDB домов записи первичных ключей вместе с ROWIDs. Что интересно в использовании gen_clust_index, так это тот факт, что любые неуникальные индексы, которые вы создаете, всегда будут иметь соответствующий rowid для gen_clust_index таблицы. Таким образом, всегда есть двойной поиск индекса, один для вторичного индекса и один для gen_clust_index.
Любые попытки улучшить макет таблицы или первичного ключа сводятся на нет из-за gen_clust_index или, по крайней мере, в крайнем случае, в лучшем случае.
ПРИМЕР
Некоторые люди пытаются отсортировать MyISAM в порядке PRIMARY KEY. Согласно MySQL Database Design and Tuning, параграф 7, под подзаголовком «Хранение таблицы в порядке индекса»:
Если вы часто получаете большие диапазоны индексированных данных из таблицы или последовательно сортируете результаты по одному и тому же ключу индекса, вы можете рассмотреть возможность запуска myisamchk с параметром --sort-records. При этом MySQL сортирует данные таблицы в том же физическом порядке, что и индекс, и может помочь ускорить такие операции. В качестве альтернативы вы можете объединить оператор ALTER TABLE с опцией ORDER BY определенного столбца для достижения тех же результатов.
Конечно, это работает и эффективно работает для MyISAM . Вы можете выполнить команду ALTER TABLE ... ORDER BY col1, col2, ..., coln для InnoDB, где столбцы могут быть или не быть столбцами PRIMARY KEY. Это не даст более быстрых результатов для InnoDB, потому что ... это верно ... вы должны обращаться к gen_clust_index каждый раз.
Некоторые люди могут использовать формат строки таблицы FIXED ALTER TABLE mydb.mytb ROW_FORMAT=Fixed;
и могут увеличить производительность чтения на 20% без каких-либо других изменений. Это работает и работает эффективно для MyISAM . Это не даст более быстрых результатов для InnoDB, потому что ... это верно ... вы должны обращаться к gen_clust_index каждый раз.
Вы можете выполнить следующее для таблицы InnoDB с именем mydb.mytb:
CREATE TABLE mydb.mytc LIKE mydb.mytb;
INSERT INTO mydb.mytc SELECT * FROM mydb.mytb ORDER BY col1,col2,...coln;
ALTER TABLE mydb.mytb RENAME mydb.mytd;
ALTER TABLE mydb.mytc RENAME mydb.mytb;
DROP TABLE mydb.mytd;
Это поместит таблицу в порядке rowid в gen_clust_index. В лучшем случае это может привести к незначительным результатам для InnoDB, потому что ... это верно ... вы должны обращаться к gen_clust_index каждый раз.
Теперь давайте немного смешно. Существует интерфейс NoSQL для запроса (только SELECT) MyISAM и InnoDB, называемый интерфейсом HandlerSocket (ранее назывался HANLDER) . Это дает вам доступ к данным, что позволяет обходить все протоколы SQL, ACID и MVCC . Хотя это возможно, ИМХО ПУТЬ СЛИШКОМ СЛОЖЕН ДЛЯ КОДИРОВАНИЯ И ОБСЛУЖИВАНИЯ. AFAIK в печати ничего не говорится о том, взаимодействует ли интерфейс HandlerSocket с gen_clust_index или нет.
Таким образом, существует много способов кожи для кошки. В этом случае вы не можете схватить кота (gen_clust_index). Я предполагаю, что именно поэтому MyISAM продолжает существовать благодаря своей производительности чтения, гибкости в упорядочении таблиц, формату строк таблицы и инструментам, поддерживающим ее. InnoDB будет оставаться разработанным в соответствии с ACID-совместимым характером, пока какая-нибудь храбрая душа не возьмет исходный код InnoDB и не превратит его во что-то лучшее из MyISAM и InnoDB .
Кластерный индекс , возможно , причина для выполнения параллелизма InnoDB по традиционным спиновым дискам.
Доступ к строке через кластеризованный индекс быстрый, потому что данные строки находятся на той же странице, куда ведет поиск по индексу. Если таблица большая, архитектура кластерного индекса часто сохраняет операции ввода-вывода на диске по сравнению с организациями хранения, которые хранят данные строк, используя страницу, отличную от записи индекса. (Например, MyISAM использует один файл для строк данных, а другой - для записей индекса.)
Дисковый ввод-вывод стоит дорого. Таким образом, сокращение этого является огромным преимуществом для улучшения параллелизма.
Если дисковый ввод-вывод начинает дешеветь и становится все более узким местом (например, когда технология SSD становится более стабильной), Oracle может решить изменить работу индексов InnoDB. Скорее всего, он останется прежним, потому что та же технология сделает «ограничение ОЗУ» менее проблемной.
Краткий ответ: Нет.
InnoDB кластеризуется через первичный ключ, и при отсутствии первичного ключа он выбирает первый уникальный индекс. При отсутствии уникального индекса он создает скрытый 6-байтовый ключ для кластеризации.
Когда у вас есть скрытый 6-байтовый ключ, любые вторичные индексы ссылаются на этот ключ, а не на точные указатели на расположение строк (как в MyISAM), поэтому вы в конечном итоге получаете обход вторичного ключа, а затем обход первичного ключа для поиска ваших записей. ,
Чтобы немного экстраполировать ваш вопрос, я предполагаю, что вы беспокоитесь о соответствии памяти дереву, потому что для эффективного поиска все корневые узлы должны быть в памяти, так как вам всегда нужно идти по этому пути, чтобы найти свои листовые страницы?
Это правда, но одно утешение заключается в том, что коммерческие базы данных стараются сделать свои деревья как можно более толстыми, а не глубокими. Попробуйте запустить xtrabackup --stats для ваших данных, чтобы увидеть. Например:
<INDEX STATISTICS>
table: test/table1, index: PRIMARY, space id: 12, root page 3
estimated statistics in dictionary:
key vals: 25265338, leaf pages 497839, size pages 498304
real statistics:
level 2 pages: pages=1, data=5395 bytes, data/pages=32%
level 1 pages: pages=415, data=6471907 bytes, data/pages=95%
leaf pages: recs=25958413, pages=497839, data=7492026403 bytes, data/pages=91%
Было 497839 листовых страниц (~ 8 ГБ), но только 416 страниц выше (6,5 МБ). Я несколько раз запускал эту команду для производственных данных, и меня всегда удивляет, когда у меня миллионы и миллиарды записей, и только страницы 1-3 уровня + листовые страницы.