質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Q&A

解決済

2回答

8702閲覧

なかったら insert あったら何もしない

退会済みユーザー

退会済みユーザー

総合スコア0

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

0グッド

0クリップ

投稿2019/07/25 11:58

user_id x campaign_id の複合インデックスがはってあるテーブルがあって

INSERT INTO ad_user_covers(user_id, campaign_id) VALUES ('test_id', 1) ON DUPLICATE KEY UPDATE ;

のような感じでペアデータがなかったら insert したいのですが
UPDATE の後に何か式をかかないとエラーになってしまうようです

どうかけばいいんでしょうか

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

キー重複していたらUPDATE・・が仕様ですが、
とりあえずキーをキーで更新しては?

sql

1INSERT INTO ad_user_covers(user_id, campaign_id) 2 VALUES ('test_id', 1) 3 ON DUPLICATE KEY UPDATE user_id=user_id and campaign_id = campaign_id 4 ; 5

投稿2019/07/25 12:10

m.ts10806

総合スコア80852

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/07/25 12:15

なるほどです なんか無駄な感じもするんですが動いたのでこれで行きたいと思います
m.ts10806

2019/07/25 12:20

無駄な感じがするのでしたらINSERT前にSELECTですね。 余程のデータ数を処理するのでなければ一発で済まそうとしなくても良いと思います。
退会済みユーザー

退会済みユーザー

2019/07/25 12:31

データ数は常に1ですがこの処理自体を呼ぶAPIがかなりの頻度で呼ばれるので 一応パフォーマンス最優先の方法をとりたいです
maisumakun

2019/07/25 13:27 編集

実際に調べてみないとわからないですが、判定して「あったら何もしない」ほうが、常にINSERT/UPDATEを行うより負荷軽減になることも考えられます。 ※文意が正反対となっていたのを修正しました。
m.ts10806

2019/07/25 12:54

計測したわけではないですが、必ずUPDATE行うのでバッファたまっていって結果的に遅くなるとかありそうですね。
hentaiman

2019/07/25 14:52

パフォーマンス優先ならAPIを実行するサーバーとDBサーバーが同一かどうかも書いた方が適切な回答もらえるんではないかと 同一ならソケットで繋げてselectで判定した方が速いと思うし、別ならmtsさんの方法が速い。たぶんね
m.ts10806

2019/07/25 21:24

環境やデータにもよるので厳密に求めるなら手元でそれなりの試行回数で検証するしかないですね。
退会済みユーザー

退会済みユーザー

2019/07/26 03:12

> APIを実行するサーバーとDBサーバー 別サーバーです
退会済みユーザー

退会済みユーザー

2019/07/26 03:17 編集

> 判定して「あったら何もしない」ほうが、常にINSERT/UPDATEを行うより負荷軽減になる そうなのですね ただ現在のシステムでは API側はCPU MySQL 側は IOPS? が問題になっています なのでCPUを使う処理はなるべく MySQL にまかせてかつ MySQL 側の IOPS は減らしたいです (実行時間自体は1秒をこえるとかでなければそれほどネックにはなってないです) IOPS が具体的にどういうクエリで増減するのか理解してないのですが とりあえずなるべく1度にクエリを発行したほうがキャッシュが効くのでいいのかなと思ってます
退会済みユーザー

退会済みユーザー

2019/07/26 03:19

>厳密に求めるなら手元でそれなりの試行回数で検証 そうですね とりあえずまだロジックの実装段階なので テストは他の方がやってくれるみたいでそこで問題になればまた考えることにします いろいろとコメントありがとうございました
guest

0

手抜きで済ませたいならINSERT IGNOREというものがあります(MySQL公式)。

ただし、INSERT IGNOREキー重複以外のエラーも無視されますので、厳密にやりたければトランザクションを開いてSELECTを行い、なければINSERTするという正統派の手順をふむことになります。

投稿2019/07/25 12:08

maisumakun

総合スコア145192

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/07/25 12:17

回答ありがとうございます INSERT IGNOREは真っ先にでてきたんですがおっしゃるとおり使うなという記事がでてきたので 2回に分けるのはパフォーマンスへの影響が大きいので duplicate key update で同じ値を代入する方法で実装することにしました
origa3

2023/12/01 23:03

maisumakunさん 恐れ入りますがトランザクションを開くのはどういう効果があるのでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問