지금껏 단순하게 update 가 insert on duplicate key update 구문보다 더 빠를 것이라 생각했습니다. 물론 update의 조건절(where)에는 pk가 주어지는 상태일 경우를 말합니다.

테이블 구조는

  1. CREATE TABLE egg_table (
  2. url varchar(255) NOT NULL default '',
  3. title varchar(255) default NULL,
  4. PRIMARY KEY (url)
  5. ) ENGINE=MyISAM

입니다. 그리고 흔하게 사용하는

  1. 존재하는가 = select title from egg_table where url = 'http://egg.pe.kr/XXX';
  2. if 존재하는가 == 응 {
  3. update egg_table set title = 'new title' where url = 'http://egg.pe.kr/XXX';
  4. } else {
  5. insert into egg_table (title, url) values ('new title', 'http://egg.pe.kr/XXX');
  6. }

형태의 로직을 좀더 깔끔하게 해보려고

  1. insert into egg_table (title, url) values ('new title', 'http://egg.pe.kr/XXX') on duplicate key update title = 'new title';

를 사용해서 잘 사용하고 있었는데요. 문득 이런 생각이 들었습니다.

insert하는 경우보다 update하는 경우가 압도적을 많은 경우 오히려 update 한 후 insert를 하는 게 조금더 효과적이지 않을까 하는 그런 생각. 그래서

  1. update egg_table set title = 'new title' where url = 'http://egg.pe.kr/XXX';
  2. if 바뀐 rows 수 == 0 {
  3. insert into egg_table (title, url) values ('new title', 'http://egg.pe.kr/XXX');
  4. }

를 해봤는데요. 잘 되는 것 같았지만 일단 update 구문을 실행할 경우 새로 바뀌는 데이터가 없을 때 바뀐 row의 수는 0입니다. 따라서 duplicate key 오류를 반환하지요.

하지만!! 무조건! 항상! 바뀌는 경우는 update 후 없는 경우만 insert하는 것이 더 효과적이지 않을까 라는 생각을 해보려고 실제 테스트를 해보았습니다.

정말 정말 단순하게 3000번의 query를 요청해서 -_-ㅋ

  1. for (i = 0; i < 3000; i++) {
  2. update ....

    if affected rows num == 0 then insert ....

  3. }
  4. for (i = 0; i < 3000; i++) {
  5. insert .... on duplicate key update ...
  6. }

결과는... 대충 2.0221 대 1.1518 이라는 수가 나왔습니다. 다시말해 insert ... on duplicate key update 가 빠르다는 결론이 나왔습니다. 물론 요청 하나에 하나의 query만 실행한다면 별다른 차이는 없겠지만 여하튼 예상했던 결과와는 다르게 나왔습니다.

제가 잘못 테스트 한 것일까요... 음...