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

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

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

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

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

3回答

3686閲覧

mysqlでのSQL速度の改善について

dsk777

総合スコア34

MySQL

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

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

2クリップ

投稿2017/07/25 07:00

編集2017/07/25 14:00

mysqlでのSQLについてアドバイスをいただきたく、投稿しました。

以下のようなDBレコードが、現在、120,000件程存在します。

idthis_keyref_keycreated_at
1AAA2017-07-21
2BBBZZZ,AAA2017-07-22
3CCCAAA2017-07-23
4DDDBBB2017-07-24

以下、クリエイト文です。

create table ( id BIGINT AUTO_INCREMENT, this_key TEXT, ref_key TEXT, created_at datetime, INDEX( id, this_key(150), ref_key(150), created_at ) )

ref_key に含まれる文字列を this_key で参照し、レコードの相関表を出力する次のようなSQLを流しました。

select A.id, min(B.id) from hoge as A left join hoge as B on ( B.ref_key like concat( '%', A.this_key , '%' ) and B.created_at >= A.created_at ) group by A.id order by A.id;

想定される出力結果は次のとおりです。

A.idB.id
12
24
3NULL
4NULL

が、レコード件数増加にともない、このSQL文が処理が終わらず、戻ってこなくなりました。
(数時間たっても反応が無い状態です)

レコード数が1000件前後だったころは、問題もなく処理できていたのですが、
増加に伴いレスポンスが著しく低下してきている現状です。

ref_key に対する like演算子の影響で indexは機能していない状態なのですが、
速度の改善がみられるようなSQL文の記述方法、別のアプローチなどあれば、アドバイスいただけないでしょうか?

どうぞ、よろしくお願い申し上げます。

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2017/07/25 07:18

インデックス情報がわかるように、CREATE TABLE で提示してください。
guest

回答3

0

ベストアンサー

1つのカラムに複数の情報を入れていますね。これはリレーショナルモデルデータベースで最もやってはいけない手法のひとつです。DBの操作が非常に煩雑になる上にパフォーマンスは出ないし、データの整合が容易に起きてしてしまいます。

これを解決するには、this_key と ref_key の関係を表した 交差テーブル を作ることです。内容は下記のような感じです:

this_keyref_key
BBBZZZ
BBBAAA
CCCAAA
DDDBBB

こうしたデータベース設計のやっていけない事とその解決法をあつめた「SQLアンチパターン」という鉄板本があります。同著では今あなたが陥っている問題を Jaywalking(信号無視) というタイトルで紹介しています。すばらしい本ですので、ぜひ買って読んでみてください。

投稿2017/07/25 07:19

miyahan

総合スコア3095

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

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

dsk777

2017/07/25 07:45

なるほどです。勉強になりました。確かにこのアプローチで実現できそうです。書籍も買わせていただきました。
dsk777

2017/07/25 13:59

交差テーブルを作成することで5分ほど処理が完了するようになりました。 ありがとうございました。
guest

0

this_keyとref_keyがどうリンクしているのかよくわかりません。
普通に正規化してはいけないのでしょうか?
ちなみに前方後方一致「%文字%」はインデックスが効かないので遅いはずです

問題点

もともとテーブルの定義もおかしいです。

(1)ref_keyの重複にたいしてcreate_atが同じ日が存在した場合
どちらのidを取っていいかわかりません

idthis_keyref_keycreated_at
1AAA2017-07-21
2BBBZZZ,AAA2017-07-22
3CCCAAA2017-07-23
4DDDBBB2017-07-24
5EEEAAA2017-07-22

(2)this_keyに重複がないという保証がありません
idはauto_incrementとのことなのできっとユニークなのでしょう

idthis_keyref_keycreated_at
1AAA2017-07-21
2BBBZZZ,AAA2017-07-22
3CCCAAA2017-07-23
4DDDBBB2017-07-24
2AAA2017-07-25

投稿2017/07/25 07:09

編集2017/07/25 07:58
yambejp

総合スコア114769

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

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

dsk777

2017/07/25 07:24

ありがとうございます。 正規化というのは、this_keyとref_keyが完全に一致するように加工する?というイメージでしょうか? このテーブル、実際のデータは、メールヘッダーのIDとReferencesがそれぞれthis_keyとref_keyに格納されています。 その為、Referencesの性質上、ref_keyの内容は性質上、これまでのメールの履歴(IDが羅列されたもの)となっており、 部分一致を使っての検索をおこなっている次第です。 おっしゃるとおり、完全一致ですとINDEXも効き、速度も大幅に改善するのが確認は取れましたが、 データとしての整合性が取れていませんでした。
guest

0

like検索してる時点で手筋が限られててしまうのですが...。
方針としてはおそらくご理解していると思いますが、
0.hogeを正規化してもつ
のがベストです。これが無理な場合、私が思いつくところでは
1.hogeテーブルの更新に追随して変更されるようなindex付テーブルをつくる(Oracleのマテリアライズドビュー)
2.全文検索+FullTextつかう。
とかでしょうか(hogeテーブルの更新頻度とリアルタイム性要求で最適解は変わってくると思いますが)?
1はよくトリガーつかった方法が紹介されていますが、多分若干のラグがあるんじゃないかと思います。
(トランザクションはれば確実にatomicにできますが)
2は割とクセの有る動きをするので使いにくい代物ですが、質問の内容では問題ない可能性もあります。

投稿2017/07/25 07:44

kurokoba

総合スコア276

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

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

dsk777

2017/07/25 14:01

ありがとうございます。 無事、別表を一旦作成し、indexを貼ることで速度改善を実現することができました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問