|
|
|
Сохранение скорости апдейта при росте таблице
|
|||
|---|---|---|---|
|
#18+
Таблица выглядит так: 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 ; Количество записей - 1057668 Данные 53.6 МБ Индекс 14.5 МБ Всего 68.1 МБ Выполнение запроса вида "UPDATE map SET positionX=12 WHERE ID=777" на базе с нулевой нагрузкой происходит за 0.06-0.08 сек. Можно ли как-нибудь сократить это время, или это объективный предел (в смысле, оптимизировать тут просто нечего)? В будущем планируется, что в таблице будет 40-50 млн. записей. Будут ли какие проблемы со скоростью апдейта? Индекс, по идее, вырастет примерно в 50 раз, т.е., составит 750Мб. Подозреваю, если по какой-то причине он не поместится в память (это не единственная таблица в БД), время апдейта увеличится существенно? Что можно предпринять заранее? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2013, 12:17:41 |
|
||
|
Сохранение скорости апдейта при росте таблице
|
|||
|---|---|---|---|
|
#18+
а вы ТОЧНО не путаете примари кей и вторичный индекс? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2013, 12:46:00 |
|
||
|
Сохранение скорости апдейта при росте таблице
|
|||
|---|---|---|---|
|
#18+
Ну, как сказать... ... PRIMARY KEY (`ID`), ... В апдейте: UPDATE map SET positionX=12 WHERE ID=777 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2013, 12:49:38 |
|
||
|
Сохранение скорости апдейта при росте таблице
|
|||
|---|---|---|---|
|
#18+
МихаилКИндекс, по идее, вырастет примерно в 50 раз, т.е., составит 750Мб. А каким боком тут ваш этот индекс? Используемый индекс (который PRIMARY KEY (`ID`) ) - он вообще кластерный и места на диске не занимает, а от индекса KEY `userID` (`userID`) скорость выполнения этого запроса не зависит в принципе. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2013, 13:15:04 |
|
||
|
Сохранение скорости апдейта при росте таблице
|
|||
|---|---|---|---|
|
#18+
AkinaА каким боком тут ваш этот индекс? Используемый индекс (который PRIMARY KEY (`ID`) ) - он вообще кластерный и места на диске не занимает Да, так и оказалось. Удалил второй индекс и действительно ноль. Так какое резюме? 50 млн - чепуховый объем и мне даже не париться на этот счет? Текущий размер таблицы на диске 53.6Мб, в 50 раз больше - примерно 2.5Гб. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2013, 13:22:16 |
|
||
|
Сохранение скорости апдейта при росте таблице
|
|||
|---|---|---|---|
|
#18+
авторон вообще кластерный и места на диске не занимает не занудства ради а истины для - таки занимает, но мало. корневые станицы же. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2013, 14:00:23 |
|
||
|
Сохранение скорости апдейта при росте таблице
|
|||
|---|---|---|---|
|
#18+
ScareCrowне занудства ради а истины для - таки занимает, но мало. корневые станицы же. Структура хранения данных в InnoDB такова, что эта хрень (кластерный индекс и всё на него повязанное) имеет место быть всегда - даже если в структуре таблицы вообще нет ни одного индекса. А посему - это накладнЫе расходы на существование самогО объекта (ака таблица), а не на существование одной из структур (ака индекс), связанных с ним. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2013, 16:31:59 |
|
||
|
Сохранение скорости апдейта при росте таблице
|
|||
|---|---|---|---|
|
#18+
МихаилКНу, как сказать... ... PRIMARY KEY (`ID`), ... В апдейте: UPDATE map SET positionX=12 WHERE ID= 777 Как вы получили это значение? Почему именно 777 ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2013, 16:50:31 |
|
||
|
Сохранение скорости апдейта при росте таблице
|
|||
|---|---|---|---|
|
#18+
Это просто пример запроса. Любое число от 1 до миллиона, результат тот же. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2013, 20:10:33 |
|
||
|
Сохранение скорости апдейта при росте таблице
|
|||
|---|---|---|---|
|
#18+
МихаилКЭто просто пример запроса. Любое число от 1 до миллиона, результат тот же.то есть в реальном коде вам все равно, что обновлять, лишь бы написать UPDATE? Тогда может быть, вообще не указывать ID? Код: sql 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2013, 20:34:10 |
|
||
|
Сохранение скорости апдейта при росте таблице
|
|||
|---|---|---|---|
|
#18+
Cygapb-007, Не понимаю Вашей озабоченности конкретным числом 777. Как уже было сказано, это всего лишь пример явно заданной константы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2013, 20:40:22 |
|
||
|
Сохранение скорости апдейта при росте таблице
|
|||
|---|---|---|---|
|
#18+
miksoftCygapb-007, Не понимаю Вашей озабоченности конкретным числом 777. Как уже было сказано, это всего лишь пример явно заданной константы.Возможно, я и не прав, но (ПМСМ) поле ID в таблице MAP не может быть получено ниоткуда, кроме самой этой таблицы. Тогда каким образом в программе можно узнать, что нам требуется именно строка с id=777? Вероятнее всего, нужная строка определяется по остальным полям - userID,objectID. А если так - то нужны ли вообще как это поле, так и и первичный ключ по этому полю? Все равно в связях к этой таблице будет что-то вроде Код: sql 1. Если ID - всего лишь дань моде вставлять в каждую таблицу (надо или не надо) автонумератор, то от него нужно избавиться. В качестве первичного ключа нужно указать пару полей (userID,objectID). Такой первичный ключ, в отличие от "ниочемного" ID, предотвратит дублирование значений этих полей в таблице. Если же значения полей userID,objectID могут дублироваться - то это нарушение 3нф В этом случае map.ID - необходимое поле, но формируется оно в другой таблице, а в map - FK на ту таблицу, но никак не AUTO_INCREMENT Вот поэтому я и заинтересовался происхождением числа 777. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2013, 21:45:01 |
|
||
|
Сохранение скорости апдейта при росте таблице
|
|||
|---|---|---|---|
|
#18+
Cygapb-007Возможно, я и не прав, но (ПМСМ) поле ID в таблице MAP не может быть получено ниоткуда, кроме самой этой таблицы.Вариантов - легион. Например, открывает пользователь документ. Вдруг ему надо узнать, например, фамилию человека, который этот документ создал. В документе есть ссылка на ID пользователя-создателя. Вот тогда в базу и отправляется запрос типа SELECT fio FROM usertable WHERE id=333. На таблицу, помимо самой таблицы, могут ссылаться и другие таблицы, и пользовательский ввод (как ручной, так и из файлов). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2013, 22:17:54 |
|
||
|
Сохранение скорости апдейта при росте таблице
|
|||
|---|---|---|---|
|
#18+
Cygapb-007Возможно, я и не прав, но (ПМСМ) поле ID в таблице MAP не может быть получено ниоткуда, кроме самой этой таблицы. Тогда каким образом в программе можно узнать, что нам требуется именно строка с id=777? Сервер обрабатывает пакеты действий, присланные клиентом. Сначала действия накатываются на модели, если все действия валидны, измнения модели отражаются в базе. К моменту сохранения изменений модели в базе все первичные ключи всех записей, которые нужно проапдейтить, известны. Просто потому что они есть в модели. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2013, 23:10:48 |
|
||
|
Сохранение скорости апдейта при росте таблице
|
|||
|---|---|---|---|
|
#18+
miksoft, именно из-за ляма вариантов я и задал вопрос конкретно к ТС :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2013, 23:34:32 |
|
||
|
Сохранение скорости апдейта при росте таблице
|
|||
|---|---|---|---|
|
#18+
МихаилК, Но на вопрос, откуда в модели возник номер 777 — вы так и не ответили :) Впрочем, не хочу разводить флейм на пустом месте. Если вас ничего не смущает, то мне и подавно фиолетово:) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2013, 23:40:56 |
|
||
|
Сохранение скорости апдейта при росте таблице
|
|||
|---|---|---|---|
|
#18+
Cygapb-007Но на вопрос, откуда в модели возник номер 777 — вы так и не ответили :) Сейчас модель считывается из БД перед обработкой пакета запросов. В дальнейшем планируется использовать мемкеш, чтобы считывать ее один раз при коннекте и затем лазить в бд только с апдейтами. Естественно, про негарантированное хранение в мемкеше все в курсе. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.08.2013, 23:53:46 |
|
||
|
Сохранение скорости апдейта при росте таблице
|
|||
|---|---|---|---|
|
#18+
МихаилКCygapb-007Но на вопрос, откуда в модели возник номер 777 — вы так и не ответили :) Сейчас модель считывается из БД перед обработкой пакета запросов. В дальнейшем планируется использовать мемкеш, чтобы считывать ее один раз при коннекте и затем лазить в бд только с апдейтами. Естественно, про негарантированное хранение в мемкеше все в курсе.Окей, я понял. Где-то в интерфейсе осущестляется связка по user_id и object_id с данными этой таблицы, вносятся изменения в какую-то строку, и в сервер посылается запрос на изменение по id этой строки (вместо изменения по user_id и object_id). Не совсем логично - ну да пусть его, это ваш проект. Вопрос снимаю, спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2013, 00:01:40 |
|
||
|
Сохранение скорости апдейта при росте таблице
|
|||
|---|---|---|---|
|
#18+
Еще одно маленькое замечание. Если описанная мной схема верна – удалить индекс (user_id,object_id) — опрометчивое решение. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2013, 00:05:43 |
|
||
|
Сохранение скорости апдейта при росте таблице
|
|||
|---|---|---|---|
|
#18+
Cygapb-007Где-то в интерфейсе осущестляется связка по user_id и object_id с данными этой таблицы, вносятся изменения в какую-то строку, и в сервер посылается запрос на изменение по id этой строки (вместо изменения по user_id и object_id). Не совсем логично - ну да пусть его, это ваш проект. На самом деле, идея не моя, но суть пакетной обработки действий через модель заключается как раз в том, что сокращается количество апдейтов бд, поскольку не пишутся промежуточные варианты. Например, пользователь userID передвигал объект objectID в перемешку с другими действиями 10 раз. Если каждому его действию будет соответствовать один запрос, то это будет 10 апдейтов. А при прогонке через модель - только один. То же самое, например, при покупке разных предметов на склад. При стандартной схеме у нас на каждую операцию один апдейт баланса в таблице пользователя и один инсерт/апдейт в таблице склада. При пакетной обработке 10 запросов на покупку разных предметов на слад у нас только один апдейт баланса в таблице пользователя и гарантированно не больше инсертов/апдейтов в таблице склада (позиции с одним itemID будут объединены в один инсерт/апдейт). А, например, в случае, когда предмет покупается на склад, а потом идет в производство, то при пакетной обработке таблица склада вообще не трогается, а при стандартном подходе - сначала будет запись прихода в таблицу склада, потом запись списания. Короче, не все так очевидно, как кажется на первый взгляд. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2013, 00:18:26 |
|
||
|
Сохранение скорости апдейта при росте таблице
|
|||
|---|---|---|---|
|
#18+
МихаилК, С идеей пакетной обработки я не спорю, но ей ни в коей мере не противоречит фиксация изменений в базе не по надуманному «номеру строки», а по «родной» связке юзера и объекта, по которой, собственно, и была доставлена в обработку исправленная запись (то есть по «естественному первичному ключу»). Поле id имеет право на существование, если на эту таблицу есть ссылки в других (дочерних для нее) таблицах, но для обеспечения FK полю id достаточно auto_increment unique not null, оно не является первичным ключем таблицы в смысле поиска в ней данных со строны «родительских» таблиц. И снова — это чисто ИМХО, просто вариант для подумать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2013, 00:37:50 |
|
||
|
Сохранение скорости апдейта при росте таблице
|
|||
|---|---|---|---|
|
#18+
Cygapb-007Если ID - всего лишь дань моде вставлять в каждую таблицу (надо или не надо) автонумератор, то от него нужно избавиться. В качестве первичного ключа нужно указать пару полей (userID,objectID). Такой первичный ключ, в отличие от "ниочемного" ID, предотвратит дублирование значений этих полей в таблице.Ага, особенно удобно после этого делать внешние ключи на записи такой таблицы К тому же (внезапно) в иннодб этот "автонумератор" всё равно есть, даже если вы его не создавали явно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2013, 05:57:58 |
|
||
|
Сохранение скорости апдейта при росте таблице
|
|||
|---|---|---|---|
|
#18+
tanglirCygapb-007Если ID - всего лишь дань моде вставлять в каждую таблицу (надо или не надо) автонумератор, то от него нужно избавиться. В качестве первичного ключа нужно указать пару полей (userID,objectID). Такой первичный ключ, в отличие от "ниочемного" ID, предотвратит дублирование значений этих полей в таблице.Ага, особенно удобно после этого делать внешние ключи на записи такой таблицы К тому же (внезапно) в иннодб этот "автонумератор" всё равно есть, даже если вы его не создавали явно.Не совсем так. Ести есть PK, – то в качестве кластерного идекса используется именно он. Если PK нет, то принимается ближайший UNIQUE NOT NULL, и только если нет обоих – искуственно создается автонумератор. А про удобство создания внешних ключей на таблицу — вы невнимательны… ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2013, 07:50:16 |
|
||
|
Сохранение скорости апдейта при росте таблице
|
|||
|---|---|---|---|
|
#18+
Cygapb-007и только если нет обоих – искуственно создается автонумератор. Вы неверно прочитали мануал. Этот "внутренний автонумератор" в таблицах InnoDb есть ВСЕГДА. И ещё одно - доступ к нему получить НЕЛЬЗЯ. В принципе. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 13.08.2013, 08:50:16 |
|
||
|
|

start [/forum/topic.php?fid=47&msg=38364095&tid=1836256]: |
0ms |
get settings: |
10ms |
get forum list: |
15ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
36ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
68ms |
get tp. blocked users: |
1ms |
| others: | 238ms |
| total: | 385ms |

| 0 / 0 |
