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

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

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

BigQueryは、Google Cloud Platformが提供しているビッグデータ解析サービス。数TB(テラバイト)またはPB(ペタバイト)の膨大なデータに対し、SQL風のクエリを実行し、高速で集計・分析を行うサービスです。

MySQL

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

SQL

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

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

Q&A

4回答

1068閲覧

MySQLのスロークエリを早くしたい

hang

総合スコア12

BigQuery

BigQueryは、Google Cloud Platformが提供しているビッグデータ解析サービス。数TB(テラバイト)またはPB(ペタバイト)の膨大なデータに対し、SQL風のクエリを実行し、高速で集計・分析を行うサービスです。

MySQL

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

SQL

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

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

0グッド

1クリップ

投稿2018/10/23 06:11

編集2018/10/23 06:40

環境

DB: Amazon Aurora(MySQL 5.6互換)
対象テーブルには1億レコード以上あります。

やりたいこと

以下のクエリで月毎の「レコード増加数」と「レコード数の累計」を算出しています。
実行結果は変えず、現状4分半→理想1分以内で結果が返ってくるように改善したいです。
SQLが初めてなので、どこがボトルネックになっているのかも解説していただけると助かります。
よろしくお願いいたします。

MySQL

1SELECT 2 t1.accum_date, 3 t1.count, 4 SUM(t2.count) AS accum 5FROM ( 6 SELECT 7 DATE_FORMAT(created, '%Y%m') AS accum_date, 8 COUNT(*) AS count 9 FROM 10 table 11 GROUP BY accum_date 12 ORDER BY accum_date 13) AS t1 14JOIN ( 15 SELECT 16 DATE_FORMAT(created, '%Y%m') AS accum_date, 17 COUNT(*) AS count 18 FROM 19 table 20 GROUP BY accum_date 21 ORDER BY accum_date 22) AS t2 23ON 24 t1.accum_date >= t2.accum_date 25GROUP BY 1 26ORDER BY 1 27;

Result

1+------------+----------+-----------+ 2| accum_date | count | accum | 3+------------+----------+-----------+ 4...(中略)... 5| 201808 | 10000000 | 85000000 | 6| 201809 | 15000000 | 100000000 | 7| 201810 | 20000000 | 120000000 | 8+------------+----------+-----------+ 950 rows in set (4 min 37.47 sec)

追記

EXPLAINの結果です。

+----+-------------+------------+------+---------------+------+---------+------+-----------+----------------------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------+------+---------------+------+---------+------+-----------+----------------------------------------------------+ | 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 120000000 | Using temporary; Using filesort | | 1 | PRIMARY | <derived3> | ALL | NULL | NULL | NULL | NULL | 120000000 | Using where; Using join buffer (Block Nested Loop) | | 3 | DERIVED | table | ALL | NULL | NULL | NULL | NULL | 120000000 | Using temporary; Using filesort | | 2 | DERIVED | table | ALL | NULL | NULL | NULL | NULL | 120000000 | Using temporary; Using filesort | +----+-------------+------------+------+---------------+------+---------+------+-----------+----------------------------------------------------+

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

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

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

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

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

maisumakun

2018/10/23 06:15

EXPLAINの結果も確認できますか?
hang

2018/10/23 06:40

追記しました。よろしくお願いいたします。
guest

回答4

0

まず集計単位が%Y%mだとわかっているならテーブルに専用カラムを用意して
埋め込んでおくとよいでしょう。(適当なインデックスも貼っておく)

また1億件のデータを毎回集計するのはむだなので
日次処理などで過去データは予め集計しておき、
既存の集計済みデータと当日データの集計結果を加算して処理するようにすれば
おそらく数百倍は早くなると思います。

投稿2018/10/23 06:42

編集2018/10/23 06:44
yambejp

総合スコア114747

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

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

hang

2018/10/23 07:22

回答ありがとうございます。 カラム変更する権限がないため、今回はこのクエリを早くする方向でお願いいたします><
yambejp

2018/10/23 07:28

テーブルの設計がダメなら何をやっても無駄ですよ 別のサマリーテーブルが作れないならスピードについては諦めるしかないですね。
guest

0

相関サブクエリーでの累計は試されましたか?

SQL

1SELECT 2 accum_date, 3 count, 4 (select count(*) from table where DATE_FORMAT(created, '%Y%m') <= t1.accum_date) as accum 5FROM ( 6 SELECT 7 DATE_FORMAT(created, '%Y%m') AS accum_date, 8 COUNT(*) AS count 9 FROM table 10 GROUP BY DATE_FORMAT(created, '%Y%m') 11) AS t1 12ORDER BY 1 13;

MySQL5.7ならファンクションインデックスもどきで多少は改善されそうですけどね。

改善策としては前月までのデータは集計済みとして保持しておく事が考えられます。
その際には、createdのインデックスがあるのが吉。

投稿2018/10/23 06:51

sazi

総合スコア25173

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

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

hang

2018/10/23 07:21

> 相関サブクエリーでの累計は試されましたか? 試していますが、10分以上結果が返ってこないので相関サブクエリーの方が遅いと判断して良さそうです。 > 改善策としては前月までのデータは集計済みとして保持しておく事が考えられます。 > その際には、createdのインデックスがあるのが吉。 なるほどです。 そういう権限がないため、今回はこのクエリを早くする方向でお願いいたします>< (提案してみます!)
sazi

2018/10/23 07:28

分析関数もWITHも使えないし、SQLで何とかするのは無理ぽい気がします。 後は、@変数使う位でしょうけど。
guest

0

質問にCREATE TABLE, CREATE INDEX と実行計画SQL実行計画の疑問解決には「とりあえずEXPLAIN」しよう を提示されては?
実行計画の見かた MySQLのEXPLAINを徹底解説!!

投稿2018/10/23 06:26

Orlofsky

総合スコア16415

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

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

hang

2018/10/23 06:40

追記しました。よろしくお願いいたします。
Orlofsky

2018/10/24 02:07

CREATE TABLE, CREATE INDEX は載せる気がないですか?
guest

0

経験に乏しいので参考程度の回答ですが。

どこがボトルネックか調べる方法ですが、(クエリに寄りますが)例えばサブクエリだけ走らせることで、どの時点で一番時間がかかっているかにあたりを付けることができるかと。

あと、Orderbyは最後に一度やればいいのでは?時間かかりそうですし。

また、データ件数が多いので、テーブルそのものの設定(インデックス設定したり)を見直すべきかどうかもわかればベターな気がします。

投稿2018/10/23 06:16

編集2018/10/23 06:20
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

hang

2018/10/23 06:42

回答ありがとうございます。 サブクエリは2分強だったので、2本のサブクエリが処理のほどんどを占めているようです。
退会済みユーザー

退会済みユーザー

2018/10/23 06:46

最適化されたりなんだりあると思うので、実際、最終的なクエリにおいてどうかはわかりませんが、参考にはなるのでいいかなと思います。サブクエリのOrderBy外してみたらどうでしょうか。
hang

2018/10/23 07:25

> サブクエリのOrderBy外してみたらどうでしょうか。 ほとんど変わりませんでした(誤差の範囲内かと)。 ありがとうございます。参考になります!
退会済みユーザー

退会済みユーザー

2018/10/23 07:30

あらら、そうでしたか。GroupByなどを外した単純なSelectでやってみて、それぞれ2分かかるなら、絞り込むか(要件にないので無理だとは思いますが)、インデックス貼るかぐらいですね(私が思いつく限界)。単純なSelectで早いようなら、GroupByをJoin後、最後にやるというのも手かもしれません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問