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

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

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

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

SQL

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

Amazon Redshift

Amazon Redshiftは、Amazon社が提供する 高速かつ完全マネージド型でペタバイト規模の クラウドデータウェアハウスサービスです。

Q&A

解決済

1回答

3362閲覧

SQL SELECTの実行速度が遅い場合の解決方法

yowayowanitohei

総合スコア31

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

SQL

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

Amazon Redshift

Amazon Redshiftは、Amazon社が提供する 高速かつ完全マネージド型でペタバイト規模の クラウドデータウェアハウスサービスです。

0グッド

0クリップ

投稿2021/05/06 23:31

編集2021/05/12 04:55

RedShiftにてSELECTクエリの実行速度が遅く困っています。
SQLのチューニングの方法についてあまり詳しくなく、スピード改善の参考になる記事や
クエリ中の遅くなっていると予想される箇所などよろしければお伺いしたいです。


問題が出ているのは以下の入力フォームで複数の値を同時に検索することができるSELECTです。
複数のテーブルを結合して、指定のIDかつ最新のものを1件取得するSQLになります。
phpでWHERE OR OR OR・・・で検索条件を繋いでおり。検索条件が百件を超えると遅くなってしまいます。

SQL

1SELECT stores.*,categories.category,cities.cityname 2FROM(SELECT storecode,buildcode,lat.lng,date,rank() OVER (PARTITION BY storecode ORDER BY date DESC) AS rank 3 FROM stores 4         WHERE (storecode = 'A01' AND date <= '2021-04-19') 5 OR (storecode = 'B02' AND date <= '2021-04-20') 6         OR ・・・・. OR ・・・・ 7 AS stores 8LEFT OUTER JOIN categories ON stores.buildcode = categories.buildcode 9LEFT OUTER JOIN meshcode ON (計算の為省略) = cities.meshcode 10WHERE rank = 1

上記SQLについては以前質問し、以下回答があったSQLになります。
https://teratail.com/questions/334027

実行計画は下記の通りになります。
見たことのないような桁になり検索が全く動きません。。。

XN

1 Outer Dist Key: ((((((floor((("outer".lat * 60::double precision) / 40::double precision)))::text || (floor(("outer".lng - 100::double precision)))::text) || (floor(((("outer".lat * 60::double precisi)::text) 2 Hash Cond: ("outer"."?column10?" = ("inner".meshcode)::text) 3 -> XN Hash Left Join DS_DIST_ALL_NONE (cost=1000010812381.25..1000010812383.59 rows=1 width=245) 4 Hash Cond: (("outer".buildcode)::text = ("inner".buildcode)::text) 5 -> XN Subquery Scan l (cost=1000010812372.86..1000010812375.18 rows=1 width=207) 6 Filter: (rank = 1) 7 -> XN Unique (cost=1000010812372.86..1000010812374.78 rows=32 width=65) 8 -> XN Window (cost=1000010812372.86..1000010812373.94 rows=48 width=65) 9 Partition: storecode 10 Order: date 11 -> XN Sort (cost=1000010812372.86..1000010812372.98 rows=48 width=65) 12 Sort Key: storecode, date 13 -> XN Seq Scan on stores (cost=0.00..10812371.52 rows=48 width=65) 14 Filter: (((storecode)::text = 'A01'::text) AND (date <= '2021-05-11'::date)) 15 -> XN Hash (cost=6.71..6.71 rows=671 width=59) 16 -> XN Seq Scan on categories (cost=0.00..6.71 rows=671 width=59) 17 -> XN Hash (cost=3872.85..3872.85 rows=387285 width=40) 18 -> XN Seq Scan on cities (cost=0.00..3872.85 rows=387285 width=40) 19

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

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

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

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

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

sazi

2021/05/07 00:23 編集

実行計画の結果を追記して下さい。 それから、orの条件が100件を超えると遅いのですか? それとも、結果が100件を超えると遅いのですか?
yowayowanitohei

2021/05/12 04:51

sazi様 ご指摘に気づかず申し訳ございません。 explainにて実行計画を取得し追記させていただきました。 メッシュコードはstoresテーブルから取得した緯度経度を桁ごとに計算し連結することで求めています。 求めた結果を元にcitiesテーブルより町名を取得しています。
guest

回答1

0

ベストアンサー

実行計画からは以下のSQL部分が遅いのが分かります

SQL

1SELECT storecode,buildcode,lat.lng,date 2 ,rank() OVER (PARTITION BY storecode ORDER BY date DESC) AS rank 3FROM stores 4WHERE (storecode = 'A01' AND date <= '2021-04-19') 5 OR (storecode = 'B02' AND date <= '2021-04-20') 6  OR ・・・・. OR ・・・・

取り敢えずは、storesに**(storecode, date desc)**のインデックスを追加してみてください。

改善しないようなら、インデックス付きの条件用の一時テーブルを使用するとかですね。

投稿2021/05/12 05:12

sazi

総合スコア25173

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

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

yowayowanitohei

2021/05/12 05:23 編集

sazi様 ご回答ありがとうございます。 インデックスちゃんとつけてみます! 質問してからこの5日間色々試してみたのですが、 ご指摘の部分をUNIONで検索を何度も結合する場合速度改善することはあるのでしょうか。。。。 何度もすみませんがどうぞよろしくお願い致します。
sazi

2021/05/12 05:35 編集

状況からは、storesの件数が大量だと推測されますから、unionだろうがインデックスが無ければ改善しないと思います。 今時、orをunion展開したからと言って高速になるようなDBMSは無いでしょう。 それから、storesに対してのVACUUMの実施はお勧めします。※かなり時間が掛かる事が予想される。 storesに大量にdeleteしている状況だと、不要データが邪魔をしてる可能性がありますので。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問