「INSERT .. ON DUPLICATE KEY UPDATE ..でクエリを投げているけど、99%くらいはUPDATEになっている」
「UPDATEを直接投げた方が速かったりする?」
「極端にパフォーマンス違うんだったら、UPDATEが転けてからINSERTする方式も考える」
とか聞かれたのでINSERT .. ON DUPLICATE KEY UPDATEについて調べてたんですが、
ソース読んでたら豆知識に出会ったのでメモ。
5.6.10のsql/sql_insert.ccの中でゴニョゴニョしている気配があるけど、write_record関数の中で
table->file->ha_write_row(table->record[0]してみる。
⇒何もないINSERTだとエラーになったらエラー。
⇒REPLACE INTO, INSERT .. ON DUPLICATE KEY UPDATEだと
それぞれHA_ERR_FOUND_DUPP_KEYを引っ掛けてハンドルしている。
最終的にはtable->file->ha_update_row(table->record[1], table->record[0])、
これはsql/sql_update.ccのmysql_update関数で呼んでいるのと同じ感じ。
…あれ。
REPLACE INTOの場合、この処理の`後に'DELETEのトリガー呼んでるように見えるぞ。。
BEFORE INSERTとBEFORE DELETEのトリガーを作ってみて
PlanetMySQL Voting: Vote UP / Vote DOWN
「UPDATEを直接投げた方が速かったりする?」
「極端にパフォーマンス違うんだったら、UPDATEが転けてからINSERTする方式も考える」
とか聞かれたのでINSERT .. ON DUPLICATE KEY UPDATEについて調べてたんですが、
ソース読んでたら豆知識に出会ったのでメモ。
5.6.10のsql/sql_insert.ccの中でゴニョゴニョしている気配があるけど、write_record関数の中で
table->file->ha_write_row(table->record[0]してみる。
⇒何もないINSERTだとエラーになったらエラー。
⇒REPLACE INTO, INSERT .. ON DUPLICATE KEY UPDATEだと
それぞれHA_ERR_FOUND_DUPP_KEYを引っ掛けてハンドルしている。
最終的にはtable->file->ha_update_row(table->record[1], table->record[0])、
これはsql/sql_update.ccのmysql_update関数で呼んでいるのと同じ感じ。
…あれ。
REPLACE INTOの場合、この処理の`後に'DELETEのトリガー呼んでるように見えるぞ。。
mysql56> CREATE TRIGGER tr1 BEFORE INSERT ON t2 FOR EACH ROW BEGIN INSERT INTO t3(trg, val) VALUES ('before insert', new.num); END;//
Query OK, 0 rows affected (0.00 sec)
mysql56> CREATE TRIGGER tr2 BEFORE DELETE ON t2 FOR EACH ROW BEGIN INSERT INTO t3(trg, val) VALUES ('before delete', old.num); END;//
Query OK, 0 rows affected (0.01 sec)
BEFORE INSERTとBEFORE DELETEのトリガーを作ってみて
mysql56> INSERT INTO t2 VALUES (4, now());
Query OK, 1 row affected (0.01 sec)
mysql56> SELECT * FROM t3;
+---------------------+---------------+------+
| dateval | trg | val |
+---------------------+---------------+------+
| 2013-04-02 15:49:25 | before insert | 4 |
+---------------------+---------------+------+
1 row in set (0.00 sec)
mysql56> REPLACE INTO t2 VALUES (4, now());
Query OK, 2 rows affected (0.01 sec)
mysql56> SELECT * FROM t3;
+---------------------+---------------+------+
| dateval | trg | val |
+---------------------+---------------+------+
| 2013-04-02 15:49:25 | before insert | 4 |
| 2013-04-02 15:49:39 | before insert | 4 |
| 2013-04-02 15:49:39 | before delete | 4 |
+---------------------+---------------+------+
3 rows in set (0.00 sec)
大当たりー。
ソースコードにも、「DELETEトリガーがあったら、ユーザーは俺たちのチートに気付くだろうしNE☆」って書いてあった。
えーと、何の話でしたっけ。。
PlanetMySQL Voting: Vote UP / Vote DOWN