2017/9/7 db tech showcase Tokyo 2017(JPOUG in 15 minutes)にて発表した内容です。
SQL大量発行に伴う処理遅延は、ミッションクリティカルシステムでありがちな性能問題のひとつです。
SQLをまとめて発行したり、処理の多重度を上げることができれば高速化可能です。ですが・・・
AP設計に起因する性能問題のため、開発工程の終盤においては対処が難しいことが多々あります。
そのような状況において、どのような改善手段があるのか、Oracleを例に解説します。
This is the presentation delivered by Karthik.P.R at MySQL User Camp Bangalore on 09th June 2017. ProxySQL is a high performance MySQL Load Balancer Designed to scale database servers.
2017/9/7 db tech showcase Tokyo 2017(JPOUG in 15 minutes)にて発表した内容です。
SQL大量発行に伴う処理遅延は、ミッションクリティカルシステムでありがちな性能問題のひとつです。
SQLをまとめて発行したり、処理の多重度を上げることができれば高速化可能です。ですが・・・
AP設計に起因する性能問題のため、開発工程の終盤においては対処が難しいことが多々あります。
そのような状況において、どのような改善手段があるのか、Oracleを例に解説します。
This is the presentation delivered by Karthik.P.R at MySQL User Camp Bangalore on 09th June 2017. ProxySQL is a high performance MySQL Load Balancer Designed to scale database servers.
This presentation was used for Japan Container Days 2018.
I explained the important point to use the k8s on Production environment for Japanese Audience.
7. 7
17.2.1 意図に反した結果 (3/5)
SELECT p.product_id,
COUNT(f.bug_id) AS count_fixed,
COUNT(o.bug_id) AS count_open
FROM BugsProducts p
INNER JOIN Bugs f ON p.bug_id = f.bug_id AND f.status = 'FIXED'
INNER JOIN BugsProducts p2 USING (product_id)
INNER JOIN Bugs o ON p2.bug_id = o.bug_id AND o.status = 'OPEN'
WHERE p.product_id = 1
GROUP BY p.product_id;
FROM BugsProducts p
INNER JOIN Bugs f ON p.bug_id = f.bug_id AND f.status = 'FIXED'
INNER JOIN Bugs o ON p2.bug_id = o.bug_id AND o.status = 'OPEN'
INNER JOIN BugsProducts p2
●BugsProducts p
●Bugs f
➢ bug_idで結合
➢ statusが'FIXED'
●BugsProducts p2
●Bugs o
➢ bug_idで結合
➢ statusが'OPEN'
■ Spaghetti-Query/anti/cartesian.sql
FIXEDとOPEN
のバグの組み合
わせを制限する
条件なし。。。
13. 13
17.5 解決策:分割統治を行う
● 節約の原則(the law of parsimony)
➢
まったく同じ予測をする2つの競合する理論があるとき
は、単純な方が優れている。
● この原則をSQLに当てはめると・・・
➢
まったく同じ結果セットを生む2つのクエリを選択できる
場合は、単純なクエリを選ぶべき。
14. 14
17.5.1 ワンステップずつ (1/2)
SELECT p.product_id, COUNT(f.bug_id) AS count_fixed
FROM BugsProducts p
LEFT OUTER JOIN Bugs f ON p.bug_id = f.bug_id AND f.status = 'FIXED'
WHERE p.product_id = 1
GROUP BY p.product_id;
SELECT p2.product_id, COUNT(o.bug_id) AS count_open
FROM BugsProducts p2
LEFT OUTER JOIN Bugs o ON p2.bug_id = o.bug_id AND o.status = 'OPEN'
WHERE p2.product_id = 1
GROUP BY p2.product_id;
FROM BugsProducts p
INNER JOIN Bugs f ON p.bug_id = f.bug_id AND f.status = 'FIXED'
INNER JOIN Bugs o ON p2.bug_id = o.bug_id AND o.status = 'OPEN'
INNER JOIN BugsProducts p2
SELECT p.product_id,
COUNT(f.bug_id) AS count_fixed,
COUNT(o.bug_id) AS count_open
WHERE p.product_id = 1 GROUP BY p.product_id;
USING (product_id)
デカルト積を避けるために、クエリを分割デカルト積を避けるために、クエリを分割
Spaghetti-Query/anti/cartesian.sql
Spaghetti-Query/soln/split-query.sql
18. 18
17.5.4 上司の問題を解決する
最前の解決策は、上司から求められたタスクを分割して処理すること。
■誰かが取り扱っている製品の数:
SELECT COUNT(*) AS how_many_products FROM Products;
■バグを修正した開発者の数:
SELECT COUNT(DISTINCT assigned_to) AS how_many_developers
FROM Bugs WHERE status = 'FIXED';
■開発者1人あたりの平均バグ修正数:
SELECT AVG(bugs_per_developer) AS average_bugs_per_developer
FROM (SELECT dev.account_id, COUNT(*) AS bugs_per_developer
FROM Bugs b INNER JOIN Accounts dev
ON b.assigned_to = dev.account_id
WHERE b.status = 'FIXED' GROUP BY dev.account_id) t;
■修正したバグの中で顧客から報告されたバグの数:
SELECT COUNT(*) AS how_many_customer_bugs
FROM Bugs b INNER JOIN Accounts cust ON b.reported_by = cust.account_id
WHERE b.status = 'FIXED' AND cust.email NOT LIKE '%@example.com';
19. 19
17.5.5 SQLを用いたSQLの自動的な記述
■ コラム: 複数のUPDATEステートメント生成
【例】 列 last_used の値を、各コンピュータが使用された最新の日付に設定する:
SELECT CONCAT('UPDATE Inventory '
' SET last_used = ''', MAX(u.usage_date), '''',
' WHERE inventory_id = ', u.inventory_id, ';') AS update_statement
FROM ComputerUsage u
GROUP BY u.inventory_id;
● 複雑なSQLクエリを分割すると、データの値によっ
てわずかに異なる、似たようなクエリをいくつも生
成することがある。
➢ それは煩わしいので、「コード生成」を行いましょう。
➢ 「コード生成」は、新しいコードを手で書くには非常に労
力がかかるような場面で効果的。