Задавайте вопросы, мы ответим
Вы не зашли.
Страниц: 1
Таблица innoDB, пять целочисленных полей, первичный ключ - целое с автоинкрементом, миллион записей, размер таблицы - около 70 Мб.
Апдейт полей одной записи с выборкой по индексу на базе с нулевой нагрузкой происходит за 0.06-0.08 сек.
1. Это нормальное время, мало, много? Можно ли уменьшить время выполнения запроса?
2. Прогнозируемое количество записей в этой таблице - где-то 40-50 млн. Я так подозреваю, этот дирижабль так не взлетит? Имеет смысл прямо сейчас резать таблицу на части? Например, на таблицы по 500 тысяч записей? В принципе, структура данных позволяет, там примерно 300-400 записей на одного юзера, поэтому при поиске данных по юзеру можно точно знать, в какой именно таблице искать. Или можно не париться и 50 млн. таких простых записей в одной таблице MySQL переварит нормально? Понимаю, что время апдейта увеличится, интересно, насколько.
Неактивен
Занятно.
Никто не работает с таблицами в десятки миллионов записей?
На самом деле, я прекрасно понимаю, что все зависит от железа и еще кучи факторов. Меня бы вполне устроил ответ примерно следующего содержания: "у нас была аналогичная таблица размером около 100 млн записей, время апдейта одной записи составляло в пределах 0.01 сек., добились мы этого так:...".
У меня на самом деле сейчас проект как раз в той стадии, когда я могу без большой крови заложить хранение данных в нескольких таблицах. Сейчас уже видно, что на каждые 10 тысяч пользователей будет примерно миллион записей. Я хочу сделать так, чтобы при росте примерно до 400-500 тысяч пользователей базу не трогать. Время апдейта на таблице из млн записей я вижу. Не фонтан, но в принципе приемлемо.
ЗЫ. На самом деле, в первом посте я допустил неточность.
Таблица выглядит так:
CREATE TABLE IF NOT EXISTS `map` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`userID` int(11) NOT NULL,
`objectID` int(11) NOT NULL,
`positionX` int(11) NOT NULL,
`positionY` int(11) NOT NULL,
PRIMARY KEY (`ID`),
KEY `userID` (`userID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1057669 ;
Т.е., апдейт-то идет по первичному ключу, но еще есть индекс по userID. С другой стороны, в апдейте это поле никогда не участвует, полагаю индекс для userID не перестраивается?
Неактивен
Очень странно, что у Вас нет еще одного индекса по объектам. По ним искать не будете?
Время обновления строки зависит от многих параметров:
1. Есть ли строка в кэше, или ее нужно прочитать с диска;
2. Обновляете ли Вы ID или только вторичные поля;
3. Влезают ли данные в leaf ноду (в Вашем случае — влезают, просто убедитесь, что
row_format = compact);
4. Скорость работы дисковой подсистемы;
5. Скорость работы процессоров и памяти, и т.д.
В общем случае, скорость обновления одного числа в кэшированных данных, когда над
данными нет вторичного индекса, не зависит от количества строк (точнее — поиск строки
зависит логарифмически, и вы это не заметите). Поэтому будете иметь те же 0.08 секунд
из коробки.
Тем не менее, имеет смысл запланировать шардирование (не партиционирование) в
системе заранее, чтобы не начать переписывать, когда внезапно уйдете в disk io из-за
нехватки памяти.
Неактивен
Ах, да, самое главное забыл написать. Точечные изменения не покажут ни разу
производительность системы. Вас интересует количество запросов, которое выдержит
система, за какое-то фиксированное время (i.e. 99% запросов укладываются в
0.5с). И эта чиселка будет зависеть от размера таблицы (косвенно, т.к. бо́льшая
таблица подразумевает бо́льший rps и, соответственно, больше seekов).
Ну и «в общем случае» оно не лечится. Помогает шардирование, ssd, etc. Лучше
решать конкретную задачку, когда она появляется.
Неактивен
paulus написал:
Очень странно, что у Вас нет еще одного индекса по объектам. По ним искать не будете?
Нет, такой потребности нет.
paulus написал:
Тем не менее, имеет смысл запланировать шардирование (не партиционирование) в
системе заранее, чтобы не начать переписывать, когда внезапно уйдете в disk io из-за
нехватки памяти.
Я это понимаю так, что разбиением таблицы мне заниматься бесполезно.
Запланировать шардирование в системе - это речь о том, чтобы запланировать на уровне сервера приложения переключение в зависимости от идентификатора пользователя на шард к которому он приписан? На старте, естественно считаем текущую бд шардом №1. Или что-то более существенное?
Неактивен
paulus написал:
Точечные изменения не покажут ни разу
производительность системы. Вас интересует количество запросов, которое выдержит
система, за какое-то фиксированное время (i.e. 99% запросов укладываются в
0.5с). И эта чиселка будет зависеть от размера таблицы (косвенно, т.к. бо́льшая
таблица подразумевает бо́льший rps и, соответственно, больше seekов).
А есть какой-нибудь простой способ создать нагрузку?
Отредактированно mikhailk (12.08.2013 15:46:49)
Неактивен
Шардирование — да, в начале всё на одном сервере (ну или, если планируете делать
отказоустойчивость, то мастер-реплика минимум), а потом добавлением шардов и пере-
носом пользователей по мере необходимости.
Простой способ сделать *какую-то* нагрузку — есть. Например, sysbench. Для
более точного профиля нагрузки, разумеется, придется писать что-то своё. Если уже
есть написанный код (например, веб-приложение), можно нагружать через этот код,
заодно и в связке потестируете. Например, с использованием siege.
Неактивен
Страниц: 1