🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
MySQL

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

パフォーマンス

コード効率の向上や計算に関する質問には、このタグを使ってください。

Q&A

解決済

2回答

810閲覧

mysql(5.7)におけるfrom-toテーブルの更新におけるパフォーマンス最適化について

tog

総合スコア26

MySQL

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

パフォーマンス

コード効率の向上や計算に関する質問には、このタグを使ってください。

0グッド

0クリップ

投稿2019/10/15 05:16

編集2019/10/15 07:20

MySQL 5.7を利用しております。
下記のようなfrom-to管理テーブルをある時点のデータテーブルで更新(Update)処理をおこないたいのですが、現行のフローだとパフォーマンスが悪いです。(というよりも更新クエリが返ってこないです。)
どのような更新クエリを書けば良いでしょうか?

更新前のテーブルA(275万件程度)

from_dateto_date(primary key)id(primary key)value
2018-01-012018-04-0111A
2018-04-022019-04-0111B
2019-04-029999-12-3111C
2018-05-022019-09-0122A
2019-09-029999-12-3122B
```MySQL5.7
CREATE TABLE テーブルA (
`from_date` DATE NOT NULL, `to_date` DATE NOT NULL, `id` INT(11) NOT NULL, `value` VARCHAR(50) NOT NULL, PRIMARY KEY (`to_date`, `id`)

)
COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB
;

更新情報を持ったある時点のテーブルB(170万件程度) |base_date(primary key)|id(primary key)|value| |:--|:--:|--:| |2019-10-10|1|1D| |2019-10-10|2|2C| ```MySQL5.7 CREATE TABLE `テーブルB` ( `base_date` DATE NOT NULL, `id` INT(11) NOT NULL, `value` VARCHAR(50) NOT NULL, PRIMARY KEY (`base_date`, `id`) ) COLLATE='utf8mb4_general_ci' ENGINE=InnoDB ;

更新後のテーブルA

from_dateto_date(primary key)id(primary key)value
2018-01-012018-04-0111A
2018-04-022019-04-0111B
2019-04-029999-12-3111D
2018-05-022019-09-0122A
2019-09-029999-12-3122C

現行の更新クエリ:

MySQL5.7

1update [テーブルA] A 2  inner join [テーブルB] B on A.id=B.id and B.base_date between A.from_date and A.to_date 3set A.value=B.value;

explain結果

MySQL5.7

1| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | 2| ---: | --- | --- | --- | --- | --- | --- | --- | --- | ---: | ---: | --- | 3| 1 | SIMPLE | B | \N | ALL | PRIMARY,テーブルB | \N | \N | \N | 1658424 | 100.00 | \N | 4| 1 | UPDATE | A | \N | ref | PRIMARY,テーブルA | PRIMARY | 202 | B.id | 916054 | 1.11 | Using where |

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

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

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

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

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

tog

2019/10/15 05:49

ありがとうございます。 追記致しました。
Orlofsky

2019/10/15 07:16

explain も。 これ以上は有料にします。笑
guest

回答2

0

解決済みになっていますが、解決はしていませんよね?

primaryの構成が、突合時の効率が悪いものになっています。
id同士なら仮に履歴状になっていても先ずは数件同士を突合する事で済みますが、日付同士の比較だと限定されるものは殆どない状態だと思われます。

** PRIMARY KEY ( id, to_date)**
のように両テーブルともidが前になるようにすること。

ただprimaryだと結合項目が不足するので、結合条件になっているものをすべて含んだインデックスの方が良いと思います。

投稿2019/10/15 10:02

編集2019/10/15 10:07
sazi

総合スコア25327

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

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

tog

2019/10/16 00:12

ありがとうございます。 無事解決しました。 基本的な所を理解できていなかったようです。 よくわかりました。
guest

0

ベストアンサー

テーブルA は id, from_date, to_date の3カラムでインデックスが欲しいです。
テーブルB は id, B.base_date の2カラムでインデックスが欲しいです。

インデックスを追加する前後の MySQL SQL実行計画の疑問解決には「とりあえずEXPLAIN」しよう の結果を質問に追記してください。

投稿2019/10/15 05:23

編集2019/10/15 05:29
Orlofsky

総合スコア16417

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

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

tog

2019/10/15 06:53

ありがとうございます。 やってみましたがやはり返ってこないようです。 実はこれまでクエリが返ってくるまで実行した事がありません。 5分以上かかった段階でプロセスKillをしておりました。 ですのでまずはクエリが返ってくるまで待機してみようと思います。 もしかするとパフォーマンスを最適化したところで1時間程度かかる処理なのかもしれません。
Orlofsky

2019/10/15 06:59

> テーブルA は id, from_date, to_date の3カラムでインデックスが欲しいです。 > テーブルB は id, B.base_date の2カラムでインデックスが欲しいです。 って書いたのを理解出来なかったら、お金を払って助っ人を呼んでください。
tog

2019/10/16 00:13

ありがとうございます。 選択性の高いものをもってこないといけないという事だったのですね。 解決しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問