Lock in $30 Savings on PRO—Offer Ends Soon! ⏳
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
そのSQL、もっと速くなりますよ。
Search
forcia_dev_pr
February 21, 2022
Programming
0
520
そのSQL、もっと速くなりますよ。
「FORCIA Meetup #4 高速検索を支えるPostgreSQLのノウハウ」の資料です
forcia_dev_pr
February 21, 2022
Tweet
Share
More Decks by forcia_dev_pr
See All by forcia_dev_pr
"書く文化"を仕組みで育てる──フォルシアの技術ブログ継続戦略
forcia_dev_pr
1
210
新しいおもちゃを見つけたい私がやっている情報収集
forcia_dev_pr
2
440
「Pythonの環境構築について」と記事作成で意識したこと
forcia_dev_pr
1
160
Neovim で VS Code みたいにコーディングする
forcia_dev_pr
1
180
なぜ・どうやって・何を書く? 〜技術記事を書く習慣の作り方〜
forcia_dev_pr
1
180
第8回ゆるふわオンサイト 解説スライド
forcia_dev_pr
0
120
第7回ゆるふわオンサイト解説
forcia_dev_pr
0
250
第6回ゆるふわオンサイト解説
forcia_dev_pr
0
260
よくわかるFORCIAのエンジニア旅行SaaSプロダクト開発編
forcia_dev_pr
0
920
Other Decks in Programming
See All in Programming
脳の「省エネモード」をデバッグする ~System 1(直感)と System 2(論理)の切り替え~
panda728
PRO
0
120
Canon EOS R50 V と R5 Mark II 購入でみえてきた最近のデジイチ VR180 事情、そして VR180 静止画に活路を見出すまで
karad
0
140
Rubyで鍛える仕組み化プロヂュース力
muryoimpl
0
200
AI 駆動開発ライフサイクル(AI-DLC):ソフトウェアエンジニアリングの再構築 / AI-DLC Introduction
kanamasa
11
4.2k
Developing static sites with Ruby
okuramasafumi
0
330
TerraformとStrands AgentsでAmazon Bedrock AgentCoreのSSO認証付きエージェントを量産しよう!
neruneruo
4
1.9k
開発に寄りそう自動テストの実現
goyoki
2
1.5k
AIコーディングエージェント(NotebookLM)
kondai24
0
240
Python札幌 LT資料
t3tra
7
1.1k
AIの誤りが許されない業務システムにおいて“信頼されるAI” を目指す / building-trusted-ai-systems
yuya4
6
4k
リリース時」テストから「デイリー実行」へ!開発マネージャが取り組んだ、レガシー自動テストのモダン化戦略
goataka
0
150
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
400
Featured
See All Featured
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
54k
Building a A Zero-Code AI SEO Workflow
portentint
PRO
0
200
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
410
XXLCSS - How to scale CSS and keep your sanity
sugarenia
249
1.3M
4 Signs Your Business is Dying
shpigford
186
22k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
980
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
0
100
Balancing Empowerment & Direction
lara
5
820
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
Automating Front-end Workflow
addyosmani
1371
200k
Building an army of robots
kneath
306
46k
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
45
Transcript
そのSQL、もっと速くなりますよ。 長尾 和昌 2022.02.15 FORCIA Meetup #4
自己紹介 • 長尾 和昌 (Kazumasa Nagao) • ソフトウェアエンジニア 旅行系アプリケーションの開発・保守 •
職歴 某電力会社の営業・経理 → プログラミング独学 → 起業 → 資金が底をつく → 就職 2
用語解説(バッチ処理とは) • オンライン処理のSQL エンドユーザーからのリクエストに応じて結果を返す。 数秒で完了する(べき)もの。 • バッチ処理のSQL 最新の料金在庫や商品情報などを顧客DBからコピーして 検索に必要な各種テーブルを作成する集中処理。
数十分で終わるものから数時間、なかには10時間を超えるものも。 3
バッチ処理のSQLの高速化に取り組む 4アプリケーションで計11時間短縮しました。 26.5時間 → 15.5時間(4アプリの合計) 4
高速化のノウハウを 4つ紹介させていただきます! 5
Case1. 1億レコードの超巨大テーブル 6
Case1. 1億レコードの超巨大テーブル 特に時間がかかっている処理をいくつか 調べたところ共通点が見つかりました。 7
Case1. 1億レコードの超巨大テーブル いつも同じテーブルが登場する。 8
Case1. 1億レコードの超巨大テーブル なんだこのテーブルは。 9
Case1. 1億レコードの超巨大テーブル SELECT count(*) FROM hoge1; -[ RECORD 1 ]-
count | 100000000 10
Case1. 1億レコードの超巨大テーブル でかい。 11
Case1. 1億レコードの超巨大テーブル これを見て疑問に思いました。 12
Case1. 1億レコードの超巨大テーブル このレコード、本当に全部使われているの? 13
Case1. 1億レコードの超巨大テーブル SQLをじっと眺めていると さらに共通点が見つかりました。 14
Case1. 1億レコードの超巨大テーブル hoge1 が使われるときは 必ず hoge2 もINNER JOIN されている。 (部屋IDにてJOIN)
15
Case1. 1億レコードの超巨大テーブル つまり hoge2 に存在しない部屋IDは 絶対に使われることがない。 ……と、いうことで試してみました。 16
Case1. 1億レコードの超巨大テーブル SELECT count(*) FROM hoge1 INNER JOIN hoge2 using
(部屋ID) ; -[ RECORD 1 ]- count | 8000000 17
Case1. 1億レコードの超巨大テーブル めっちゃ減った。 1億 → 800万 18
Case1. 1億レコードの超巨大テーブル hoge1 も hoge2 も顧客DBから取得した 生テーブルだったため、取得のタイミングで hoge1 に hoge2
をJOINして 不要なデータを落としました。 19
Case1. 1億レコードの超巨大テーブル これにより、hoge1 を使っている全ての SQLが爆速化しました。 計165分の大幅な短縮となりました。 20
Case1. 1億レコードの超巨大テーブル 【まとめ】 そのレコードは本当に使っているのか。 使っていないなら可能な限り上流で落とす。 21
Case2. WHERE句から条件を消したい 22
Case2. WHERE句から条件を消したい プレウォームが遅い。100分もかかる。 23
Case2. WHERE句から条件を消したい プレウォームとは バッチ処理の最後、サービス復帰の直前に 前もってよく投げられるクエリを発行し 結果をキャッシュに載せる。 24
Case2. WHERE句から条件を消したい 問題のSQLをいろいろいじっていて あることに気づきました。 25
Case2. WHERE句から条件を消したい SELECT * FROM hoge1 WHERE 方面 = ‘8’;
「方面=’8’」を消すと爆速化する。 26
Case2. WHERE句から条件を消したい これ消したい。 27
Case2. WHERE句から条件を消したい ただ、必要なので書かれているわけで 消したいからといって消せるもんじゃない。 28
Case2. WHERE句から条件を消したい 消したいなあ。でも消せないなあ。 29
Case2. WHERE句から条件を消したい あっ!!! 30
Case2. WHERE句から条件を消したい テーブルのほうを分ければよいのでは?! 31
Case2. WHERE句から条件を消したい 方面の数は有限なので もとのテーブル(hoge1)を hoge1_1, hoge1_2, hoge1_3 …… と分割しました。 32
Case2. WHERE句から条件を消したい SELECT * FROM hoge1 WHERE 方面 = ‘8’
↓ SELECT * FROM hoge1_8; 33
Case2. WHERE句から条件を消したい 重かった WHERE がなくなり プレウォームが100分から15分に短縮。 34
Case2. WHERE句から条件を消したい 【まとめ】 WHEREが重くて困ったら テーブルのほうを分けられるか確認する。 35
Case3. ループするSQLにご注意 36
Case3. ループするSQLにご注意 こんなSQLがありました。 37
Case3. ループするSQLにご注意 38 5回ループ { CREATE TABLE 新テーブル_{1~5} AS SELECT
hoge FROM Aテーブル INNER JOIN Bテーブル INNER JOIN Cテーブル INNER JOIN Dテーブル INNER JOIN Eテーブル_{1~5} ; }
Case3. ループするSQLにご注意 ん?なんか無駄じゃないか? 39
Case3. ループするSQLにご注意 40 CREATE TEMPORARY TABLE 一時テーブル AS SELECT hoge
FROM Aテーブル INNER JOIN Bテーブル INNER JOIN Cテーブル INNER JOIN Dテーブル ; 5回ループ { CREATE TABLE 新テーブル_{1~5} AS SELECT hoge FROM 一時テーブル INNER JOIN Eテーブル_{1~5} ; }
Case3. ループするSQLにご注意 これでB~DテーブルをJOINする回数が 5回から1回に減りました。 処理時間も当然ながら1/5ほどになりました。 41
Case3. ループするSQLにご注意 【まとめ】 ループさせるときは 本当にループすべきもの以外は 一時テーブルとして外だしする。 42
Case4. 理解不能な激ムズSQLでも速くしたい 43
Case4. 理解不能な激ムズSQLでも速くしたい なんだこのSQLは……読めん。 44
Case4. 理解不能な激ムズSQLでも速くしたい 45 SELECT 超複雑な処理 FROM ( SELECT 超複雑な処理 FROM
( SELECT 超複雑な処理 FROM ( -- かろうじて理解できた部分、ここから SELECT hoge FROM Aテーブル INNER JOIN Bテーブル INNER JOIN Cテーブル INNER JOIN Dテーブル INNER JOIN Eテーブル -- かろうじて理解できた部分、ここまで ) ) );
Case4. 理解不能な激ムズSQLでも速くしたい 階層深いし、ループしてるし SELECTのなかに独自実装の関数がいっぱい。 46
Case4. 理解不能な激ムズSQLでも速くしたい しかも処理が遅いのは まさにその超複雑な箇所でした。 47
Case4. 理解不能な激ムズSQLでも速くしたい この超複雑な箇所を直接触らずに しかもその箇所の速度を上げたい。 でも、そんなうまい話あるわけ…… 48
Case4. 理解不能な激ムズSQLでも速くしたい ANALYZE !! 49
Case4. 理解不能な激ムズSQLでも速くしたい かろうじて理解できた箇所を外だしして ANALYZEをかけた状態で 超複雑な処理を迎えるようにすれば…… 50
Case4. 理解不能な激ムズSQLでも速くしたい 51 CREATE TEMPORARY TABLE 一時テーブル AS SELECT hoge
FROM Aテーブル INNER JOIN Bテーブル INNER JOIN Cテーブル INNER JOIN Dテーブル INNER JOIN Eテーブル ; ANALYZE 一時テーブル; SELECT 超複雑な処理 FROM ( SELECT 超複雑な処理 FROM ( SELECT 超複雑な処理 FROM 一時テーブル ) );
Case4. 理解不能な激ムズSQLでも速くしたい たったこれだけで25%の高速化に成功しました。 52
Case4. 理解不能な激ムズSQLでも速くしたい 【まとめ】 困ったときのANALYZE 53
まとめ 54
まとめ • Case1. 1億レコードの超巨大テーブル そのレコードは本当に使っているのか。 使っていないなら可能な限り上流で落とす。 • Case2. WHERE句から条件を消したい WHEREが重くて困ったら
テーブルのほうを分けられるか確認する。 55
まとめ • Case3. ループするSQLにご注意 ループさせるときは 本当にループすべきもの以外は 一時テーブルとして外だしする。 • Case4. 理解不能な激ムズSQLでも速くしたい
困ったときのANALYZE 56
さいごに 今回ご紹介させていただいたノウハウは いずれもトリッキーな技術ではなく 「なんだそんな単純なことか」 「そんなこと既にできているに決まっている」 と思われるようなものも多々あったかと思います。 57
さいごに ただ、ひとつのSQLが数百行数千行あったとしたら どうでしょうか。 その中にたった数行問題のある重い処理が存在する ということは十分にあり得ることだと思います。 そして、それを探し出すのがSQLチューニングの 楽しさかなと思います。 58
ご清聴ありがとうございました! 59