Задача
есть таблица на несколько млн. записей
Почти все запросы это селекты выбирающие все записи по условиям типа
`node_id` = ? AND `stats_date` = ? AND `stats_type` = ?
или
`node_id` = ? AND `stats_date` = ?
или
`node_id` = ?
Остальное только вставки новых записей (апдейтов нет). Работа по вставке так и по селектам очень периодическая.
Т.е. пока никаких проблем нет - из базы все данные выбирается быстро насколько возможно из кластерного индекса.
Сейчас как все работает полностью устраивает, но т.к. записей в таблице будет еще больше и появилась необходимость добавления еще 1 простого индекса для выборки по stats_date, то возникает несколько проблем.
При создании любого дополнительного индекса в InnoDB первичный ключ неявно копируется в него, т.е. только добавив в данную таблицу 1 ключ размер данных увеличится в 2 раза.
Как вариант можно использовать автоинкрементый примари ключ + уникальный составной ключ по нужным полям вместо составного примари. Тогда да, каждый новый ключ в базе будет занимать значительно меньше места, но падает скорость выборок (у меня где-то на 10-30%), когда задействуется много записей.
Поэтому несколько вопросов:
P.S. Я прекрасно понимаю что разницы что использовать вообще нет на небольших таблицах в 100-200К записей, речь идет именно о таблицах больше 2-3млн записей
P.P.S. Моих знаний C++ недостаточно для изучения исходников Mysql
есть таблица на несколько млн. записей
Код:
CREATE TABLE `stats` (
`node_id` int(10) unsigned NOT NULL DEFAULT '0',
`stats_date` int(10) unsigned NOT NULL,
`stats_type` varbinary(25) NOT NULL,
`counter` int(10) unsigned NOT NULL,
PRIMARY KEY (`node_id`,`stats_date`,`stats_type`),
KEY `stats_date` (`stats_date`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`node_id` = ? AND `stats_date` = ? AND `stats_type` = ?
или
`node_id` = ? AND `stats_date` = ?
или
`node_id` = ?
Остальное только вставки новых записей (апдейтов нет). Работа по вставке так и по селектам очень периодическая.
Т.е. пока никаких проблем нет - из базы все данные выбирается быстро насколько возможно из кластерного индекса.
Сейчас как все работает полностью устраивает, но т.к. записей в таблице будет еще больше и появилась необходимость добавления еще 1 простого индекса для выборки по stats_date, то возникает несколько проблем.
При создании любого дополнительного индекса в InnoDB первичный ключ неявно копируется в него, т.е. только добавив в данную таблицу 1 ключ размер данных увеличится в 2 раза.
Как вариант можно использовать автоинкрементый примари ключ + уникальный составной ключ по нужным полям вместо составного примари. Тогда да, каждый новый ключ в базе будет занимать значительно меньше места, но падает скорость выборок (у меня где-то на 10-30%), когда задействуется много записей.
Поэтому несколько вопросов:
- что лучше выбрать составной PK + простой ключ или автоинкремент PK + уникальный составной + простой ключ
- где можно почитать о выделении, использовании и резервировании памяти в InnoDB при работе с кластерным индексом (по обычному есть хоть какая-то информация) и как можно узнать в реалтайме сколько он занимает в памяти? Я понимаю что скорее всего я неправильно ищу, но почти все что выдает поисковик на мои поисковые запросы - это форумы и stackoverflow, где куча предположений по типу "я думаю что память выделяется так" или "по идее это работает так", но точного ответа нет.
P.S. Я прекрасно понимаю что разницы что использовать вообще нет на небольших таблицах в 100-200К записей, речь идет именно о таблицах больше 2-3млн записей
P.P.S. Моих знаний C++ недостаточно для изучения исходников Mysql
Последнее редактирование: