teratail header banner
teratail header banner
質問するログイン新規登録
CentOS

CentOSは、主にRed Hat Enterprise Linux(RHEL)をベースにした、フリーのソフトウェアオペレーティングシステムです。

MySQL

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

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

3回答

2222閲覧

MySQLの処理速度を上げたいですが可能ですか?

HisashiSakamoto

総合スコア28

CentOS

CentOSは、主にRed Hat Enterprise Linux(RHEL)をベースにした、フリーのソフトウェアオペレーティングシステムです。

MySQL

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

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

2クリップ

投稿2019/04/09 03:19

編集2019/04/09 03:41

0

2

こんにちは、質問があるのですが、知恵をお貸しいただけますと幸いです。

現在、MySQLのDBサーバにアクセスして、Update文をFor文で何回も処理を投げています。

あるカラムの数字を+1インクリメントするようなUpdate文を投げています。

今のところ、速度的には1秒あたり25件の処理が可能です。

これをもっと速くしたいと考えているのですが、どのような方法がありそうでしょうか?
(my.cnfファイルの修正など)
マシンの部品に関する話でも知りたいと思います(CPUのコア数など)。

教えていただけますと幸いです。よろしくお願いいたします。

SQLは以下となります。

SQL

1UPDATE `DB`.`table_1` SET `remaining_count_charge` = `remaining_count_charge` - 1, `total_count` = `total_count` + 1 WHERE `id` = 1;";

SQL

1UPDATE `DB`.`table_1` SET `remaining_count_charge` = `remaining_count_charge` - 100, `total_count` = `total_count` + 100 WHERE `id` = 1;";

とすれば、100回繰り返すことと同じことに成るということは承知しております。1回ずつ、処理を行いたいのです。

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

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

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

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

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

yoorwm

2019/04/09 03:20

普通は、column_name = column_name + 1で済むものなので、そんなFor文使うなんて方法は使わないですが、具体的なSQL文を提示してみてください。
m.ts10806

2019/04/09 03:25

>速度的には1秒あたり25件の処理が可能です。 目標はいかほどでしょうか。
HisashiSakamoto

2019/04/09 03:39

UPDATE `DB`.`table_1` SET `remaining_count_charge` = `remaining_count_charge` - 1, `total_count` = `total_count` + 1 WHERE `id` = 1;"; という形です。 1回ずつ繰り返す必要がありまして、 UPDATE `DB`.`table_1` SET `remaining_count_charge` = `remaining_count_charge` - 100, `total_count` = `total_count` + 100 WHERE `id` = 1;"; とはしたくないのです。 目標ですね…。 1秒あたり100件になればありがたいと思いますが、いかがでしょうか?
sazi

2019/04/09 04:46 編集

その1件の性能はどうやって計っているんですか? 1件毎処理したいなら、前後の処理もあると推測します。 例えば、トランザクションの制御はどうなっているかも性能には影響すると思うのですが、そういった類は関係ないと判断済みですか?
cateye

2019/04/09 15:01

サーバとの回線速度が、ボトルネックになっているという事はないですか?
HisashiSakamoto

2019/04/10 14:36

トランザクションに関しては、MySQLは特別なようですね。 少し調べてみます。
HisashiSakamoto

2019/04/10 14:39

サーバとの回線速度に関しては、 ・TomcatサーバからリモートDBサーバにUpdate文を送る場合は、1件あたり0.041秒 ・TomcatサーバとDBサーバが同じマシンの場合で、Update文を送る場合は1件あたり0.018秒 となりました。2倍速度が改善されたので、少し参考にしようと思います。
HisashiSakamoto

2019/04/10 14:43

>その1件の性能はどうやって計っているんですか? JSP内にFor文でUpdate文をDBサーバに投げる処理を行い、System.currentTimeMillis()で時刻を取得し、その時刻差をFor繰り返し回数で割ってページに表示しています。
退会済みユーザー

退会済みユーザー

2019/04/11 09:43

jsqにゴリゴリコードを書いてるのか、 100回繰り返し出なければいけない理由とは?
guest

回答3

0

ベストアンサー

なぜ、100回同じクエリを投げたいのか理由がわかれば、別の回避策があるような気がしますが。

とりあえず複数回アップデートを流す場合の性能向上としてバッチアップデートというのがあります。

性能測定サンプルが以下にありましたので、試してみてはどうでしょうか。

JDBC Batch insert update MySQL Oracle

昔は、MySQLはJDBC内でforループするだけだったので、効果期待できないとあったのですが、
どうやらサポートされたのかもしれない。
動作確認したわけでないので、ダメもとでやってみたらよいかと。

あ、あと最初に書きましたが100回同じクエリー流す意図がわかれば、違う回避策あるかもしれません。

===
追記

実はある人がブラウザのあるページにアクセスすると、(リロードしなくても)5秒に1回このSQLが自動で動くようなページを作っています。
もし、これが100人が同時にこのページにアクセス中だとおおよそ0.05秒に1回このSQLが動くということになります。
この更新に耐えうる方法を期待しています。

その要件だとSQLが動かなくなる条件がないように思えますので、最終的にとんでもない数の更新になるのでは?
まぁ、その話は置いといて・・・
この場合だと、メモリ上に同期されたカウンタだけ用意して、定期的に1回アップデートで十分かなぁ。
カウンタの更新はDBより負荷が低いので余裕だと思います。
ロードバランシングしても、それぞれがカウンタを管理すればいけるかと

投稿2019/04/11 01:43

編集2019/04/16 01:26
momon-ga

総合スコア4828

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

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

HisashiSakamoto

2019/04/15 14:51

遅くなり、すいません。 実はある人がブラウザのあるページにアクセスすると、(リロードしなくても)5秒に1回このSQLが自動で動くようなページを作っています。 もし、これが100人が同時にこのページにアクセス中だとおおよそ0.05秒に1回このSQLが動くということになります。 この更新に耐えうる方法を期待しています。 ちなみに、アクセスログをとっているのではないので、ログ解析の必要は生じません。
momon-ga

2019/04/16 01:23

その要件は、質問に追記した方がよい回答を期待できるかと思います。
HisashiSakamoto

2019/04/19 13:40

皆様ありがとうございました。 最終的には、Staticな配列を用意して、そこにレコード1個を1個の要素として逐次入れていって、配列のSizeが100に達したら、SQLを発行するという方法を考えました。 これですとSQL100回を1回で済ませられそうです。 もちろん、1000回でも実行時間は10倍になりますが、それほど影響はなさそうでした。 「メモリ上に同期」というのがヒントとなりました。
guest

0

質問が単純にUPDATE文の性能を上げるという事なら、環境の性能上げるしかないんじゃないでしょうか。
どのような環境なのかも記述されておりませんので、具体的な話での回答にはなりませんが、仮想環境ならCPUコアの割り当てとかメモリの割り当てを増してみるとか。
それから、書き込みが高速なストレージに変更するとかネットワーク機器の見直しとか。

ここまで書きましたが、先にチューニングすべきは、そのUPDATEを含む一覧処理のチューニングだと思いますけどね。

投稿2019/04/09 04:53

編集2019/04/11 03:21
sazi

総合スコア25430

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

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

HisashiSakamoto

2019/04/10 14:23

SSDやテープにすれば早くなるかもしれませんね。 コア数は16個とか多ければ良さそうですが、まだ試してないです。 ネットワーク機器は、NuroでCat.6ケーブルなのですが一応DBサーバとTomcatサーバが同じマシンの中にあればこれらは考慮しなくてもいいということになりそうです。
退会済みユーザー

退会済みユーザー

2019/04/10 23:42

ボトルネックを消さずにボトルネックを解消死体といってるように見える(誤字あり)
sazi

2019/04/11 06:03

@asahina1979 さん 質問者さんは、そのコメントもこの回答に対してと思うかもしれません。 正直どういえば、伝わるのか分かりません。
退会済みユーザー

退会済みユーザー

2019/04/11 22:36

おうふ。スマホで誤爆してたか
guest

0

LAST_INSERT_ID を使ってみては?あまり改善できないかもしれませんが。
用途がわかると AUTO_INCREMENT で良いのでは?などと適切な回答が付き易いのでは?

投稿2019/04/09 03:27

Orlofsky

総合スコア16419

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

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

HisashiSakamoto

2019/04/09 03:42

少し調べて見ます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問