explain format =json
UPDATE reservations
JOIN screenings using (screening_id)
SET status = 'CANCELLED'
WHERE start_time < NOW() and status = 'PENDING';
UPDATE reservations
SET status = 'CANCELLED'
WHERE status = 'PENDING' and created_at < NOW() -INTERVAL 10 MINUTE;
DB를 폴링하면서 10분이 지나도록 예매가 완료(결제)되지 못하거나, 상영시간전까지 처리되지 못한 예매를 모두 정리합니다.
이 쿼리의 실행계획은 어떻게 될까요
{
"query_block": {
"select_id": 1,
"table": {
"update": 1,
"table_name": "reservations",
"access_type": "index",
"key": "PRIMARY",
"key_length": "",
"used_key_parts": ["reservation_id"],
"rows": 40080,
"attached_condition": "reservations.`status` = 'PENDING' and reservations.created_at < current_timestamp() - interval 10 minute"
}
}
}
인덱스를 처음부터 끝까지 다 읽는 군요
그거 아십니까?
innoDB는 인덱스에 락을 건다는 사실 말입니다.
SELECT trx_id, trx_rows_locked, trx_rows_modified FROM information_schema.INNODB_TRX;
update가 수정하는 것은 8천개밖에 되지 않는데!
락에 걸린 데이터는 40000개나 됩니다.
안타까운 사실은 이 쿼리는 스케줄러에 의해 폴링될 것이란 점입니다.
데이터가 크면 클수록 아주 끔찍한 재앙을 초래할 것입니다.