지금껏 단순하게 update 가 insert on duplicate key update 구문보다 더 빠를 것이라 생각했습니다. 물론 update의 조건절(where)에는 pk가 주어지는 상태일 경우를 말합니다.
테이블 구조는
- CREATE TABLE egg_table (
- url varchar(255) NOT NULL default '',
- title varchar(255) default NULL,
- PRIMARY KEY (url)
- ) ENGINE=MyISAM
입니다. 그리고 흔하게 사용하는
- 존재하는가 = select title from egg_table where url = 'http://egg.pe.kr/XXX';
- if 존재하는가 == 응 {
- update egg_table set title = 'new title' where url = 'http://egg.pe.kr/XXX';
- } else {
- insert into egg_table (title, url) values ('new title', 'http://egg.pe.kr/XXX');
- }
형태의 로직을 좀더 깔끔하게 해보려고
- 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를 하는 게 조금더 효과적이지 않을까 하는 그런 생각. 그래서
- update egg_table set title = 'new title' where url = 'http://egg.pe.kr/XXX';
- if 바뀐 rows 수 == 0 {
- insert into egg_table (title, url) values ('new title', 'http://egg.pe.kr/XXX');
- }
를 해봤는데요. 잘 되는 것 같았지만 일단 update 구문을 실행할 경우 새로 바뀌는 데이터가 없을 때 바뀐 row의 수는 0입니다. 따라서 duplicate key 오류를 반환하지요.
하지만!! 무조건! 항상! 바뀌는 경우는 update 후 없는 경우만 insert하는 것이 더 효과적이지 않을까 라는 생각을 해보려고 실제 테스트를 해보았습니다.
정말 정말 단순하게 3000번의 query를 요청해서 -_-ㅋ
- for (i = 0; i < 3000; i++) {
-
update ....
if affected rows num == 0 then insert ....
- }
- for (i = 0; i < 3000; i++) {
- insert .... on duplicate key update ...
- }
결과는... 대충 2.0221 대 1.1518 이라는 수가 나왔습니다. 다시말해 insert ... on duplicate key update 가 빠르다는 결론이 나왔습니다. 물론 요청 하나에 하나의 query만 실행한다면 별다른 차이는 없겠지만 여하튼 예상했던 결과와는 다르게 나왔습니다.
제가 잘못 테스트 한 것일까요... 음...
ENGINE=MyISAM
2010/06/16 18:03 [ ADDR : EDIT/ DEL : REPLY ]엔진 종류에 따라서 차이가 있지 않을까요?
그리고 index 에 접근하는 횟수 차이라던가.. 음.. 생각좀 더 해봐야겠네요 :)
엔진에 상관없이 insert ... on duplicate key update . 이 빠를수 밖에 없습니다.
2010/08/27 14:30 [ ADDR : EDIT/ DEL : REPLY ]insert 문장의 처리속도를 1로 생각하고 update 쿼리문의 처리속도를 2로 가정합니다. 그리고 쿼리 문장을 전송하는 처리속도는 일단 무시하겠습니다.
100개의 쿼리를 실행하는데 중복이 50개라고 할 때...
1. insert... on duplicate key update 를 사용했을경우
(100*1) + (50*2) = 200 입니다.
2. update and insert를 사용할 경우 에는
(100*2) + (50*1) = 250 입니다.
단순히 보아도 insert... on dup.... 가 빠르다는것을 알수 있습니다.
또 여기에 쿼리 문장을 전송하는 것을 생각하면
1. 의 경우에는 100회 전송이고 2.의 경우에는 150회를 전송해야 합니다.
만약 db서버가 원격지에 존재한다면 더욱 차이가 날수 밖에 없을겁니다.
여기서 먼저 알아 둬야 할 것은 insert 문장이 select, update, delete 보다 빠르다는 것입니다.
모두 동일한 속도를 가진다고 하여도 쿼리요청에 대한 수로 인해 1.의 경우가 2.의 경우보다 빠릅니다.
댓글을 달아 주세요