Задать вопрос
@chetupek

Как оптимизировать подобный sql?

Привет, обслуживаю некий чат, типа как диалоги в вк.
В нем для обозначения прочитанных сообщений есть таблица:

CREATE TABLE `chat_lastread` (
  `user_id` int(8) NOT NULL,
  `dialog_id` int(16) NOT NULL,
  `date` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`user_id`,`dialog_id`),
  KEY `date` (`date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


Сейчас в таблице 798 строк.
При каждом действии пользователя с сервером, происходит запрос:

$db->query('
	INSERT INTO chat_lastread (
		`user_id`,
		`dialog_id`,
		`date`
	) VALUES(
		#user_id,
		#dialog_id,
		NOW()
	) ON DUPLICATE KEY UPDATE date=NOW()'
, $user->getId(), $dialog_id);


То естьданные в таблицу пишутся постоянно.
При этом этот запрос очень сильно грузит процессор, E3-1230 на 800%

Возможно ли что то сделать с нагрузкой не меняя структуру самого приложения?
  • Вопрос задан
  • 1500 просмотров
Подписаться 2 Простой 5 комментариев
Пригласить эксперта
Ответы на вопрос 2
LaRN
@LaRN
Senior Developer
Если проблема точно в этом запросе, можно попробовать разделить запрос на две части без использования
инструкции ON DUPLICATE KEY UPDATE:

if exists(select 1
             from chat_lastread
            where `user_id`   = #user_id
              and `dialog_id` =  #dialog_id)
 begin
   update chat_lastread
      set `date` = NOW()
     from chat_lastread
    where `user_id`   = #user_id
      and `dialog_id` =  #dialog_id
 end
 else
 begin
   INSERT INTO chat_lastread (
     `user_id`,
     `dialog_id`,
     `date`
   ) VALUES(
     #user_id,
     #dialog_id,
     NOW()
   )
 end
Ответ написан
ThunderCat
@ThunderCat Куратор тега MySQL
{PHP, MySql, HTML, JS, CSS} developer
`dialog_id` int(16) NOT NULL, - 16 отображаемых знаков - тут вроде не должно быть так, там может быть максимум (11) при int, и емнип в любом случае размер отводимой памяти будет 4 байта. Если вы планируете хранить более 4 миллиардов записей используйте bigint.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы