Quantcast
Channel: 日々の覚書
Viewing all articles
Browse latest Browse all 581

複合プライマリーキー vs サロゲートキーでInnoDB読み取りページ数の比較

$
0
0

TL;DR

この考察の単位は ページ数であって パフォーマンスじゃない。パフォーマンスを考える時はこれにさらにバッファプールヒット率が関連するはず

  • COUNT(*)に関してはページあたりのインデックスレコードの充填数が多いサロゲートキーの方が読むページが少ない
  • カバリングインデックスの効くCOUNT(*)に関してはナチュラルキーのサイズの大きさはほとんど関係なさそう

  • 行本体を読まなければいけない(=カバリングインデックスで済まない)select_lsitになるとサロゲートキーの充填数の差は目立たなくなる

  • ナチュラルキーの左端でレンジスキャンする時がページ読み取り数は最小

  • 読みだすページの数だけで比べると , セカンダリキー引きはテーブルスキャンよりも読むページ数は多いことがある

日々の覚書: インデックス vs InnoDBログ書き込みのサイズ観測の続き。

今度は読み取るページ数にのみ着目。

計測方法。

### Before, Afterの累計ページ読み取り数
### After - Beforeがそのクエリで読み取ったページ数になる
SELECT name, count, status FROM information_schema.innodb_metrics WHERE name = 'buffer_pool_read_requests';

## 計測対象クエリ
### COUNT(*) -> リーフページだけ読めば足りるやつ
SELECT COUNT(*) FROM <table>;
SELECT COUNT(*) FROM <table> WHERE user_id = 0825;
SELECT COUNT(*) FROM <table> WHERE updated = ?;

### 全フィールド。クラスターインデックスに触らないといけないやつ
SELECT * FROM <table>;
SELECT * FROM <table> WHEER user_id = 0825;
SELECT * FROM <table> WHEER updated = ?;

## updatedは深く考えずにNOW()で降ってたのでバラツキがあって、
## 結果セットの行数だけ合わせるためにCOUNTしてJOINして値を決めた
mysql> WITH t1_c AS (SELECT updated, COUNT(*) AS c FROM d1.t1 GROUP BY 1),
-> t2_c AS (SELECT updated, COUNT(*) AS c FROM d1.t2 GROUP BY 1),
-> t3_c AS (SELECT updated, COUNT(*) AS c FROM d1.t3 GROUP BY 1),
-> t4_c AS (SELECT updated, COUNT(*) AS c FROM d1.t4 GROUP BY 1),
-> t5_c AS (SELECT updated, COUNT(*) AS c FROM d1.t5 GROUP BY 1)
->
->
-> SELECT c, t1_c.updated AS t1, t2_c.updated AS t2, t3_c.updated AS t3, t4_c.updated AS t4, t5_c.updated AS t5
-> FROM t1_c JOIN t2_c USING(c) JOIN t3_c USING(c) JOIN t4_c USING(c) JOIN t5_c USING(c);

c: 567
t1: 2023-02-08 00:32:39
t2: 2023-02-08 00:37:34
t3: 2023-02-08 00:44:08
t4: 2023-02-08 00:51:12
t5: 2023-02-08 00:57:38

結果。単位は「ページリクエスト」

COUNT(*)

tablewithout_WHEREwithout_WHERE_keywithout_WHERE_vs_t1WHERE_useridWHERE_userid_keyWHERE_userid_vs_t1WHERE_updatedWHERE_updated_keyWHERE_updated_vs_t1comment
t1881PRIMARY1.001286N/A(type:ALL)1.001286N/A(type:ALL)1.00auto_increment PK + 0 key
t2881idx_userid1.007idx_userid0.011286N/A(type:ALL)1.00auto_increment PK + 1 key
t3881idx_userid1.007idx_userid0.0113idx_updated0.01auto_increment PK + 2 key
t41140PRIMARY1.298PRIMARY0.011373N/A(type:ALL)1.07natural PK + 0 key
t51140idx_updated1.298PRIMARY0.0112idx_updated0.01natural PK + 1 key

all_fields

tablewithout_WHEREwithout_WHERE_keywithout_WHERE_vs_t1WHERE_useridWHERE_userid_keyWHERE_userid_vs_t1WHERE_updatedWHERE_updated_keyWHERE_updated_vs_t1comment
t11286N/A(type:ALL)1.001286N/A(type:ALL)1.001286N/A(type:ALL)1.00auto_increment PK + 0 key
t21286N/A(type:ALL)1.00308idx_userid0.241286N/A(type:ALL)1.00auto_increment PK + 1 key
t31286N/A(type:ALL)1.00308idx_userid0.241710idx_updated1.33auto_increment PK + 2 key
t41373N/A(type:ALL)1.078PRIMARY0.011373N/A(type:ALL)1.07natural PK + 0 key
t51373N/A(type:ALL)1.078PRIMARY0.011708idx_updated1.33natural PK + 1 key

まとめ

この考察の単位は ページ数であって パフォーマンスじゃない。パフォーマンスを考える時はこれにさらにバッファプールヒット率が関連するはず

  • COUNT(*)に関してはページあたりのインデックスレコードの充填数が多いサロゲートキーの方が読むページが少ない
  • カバリングインデックスの効くCOUNT(*)に関してはナチュラルキーのサイズの大きさはほとんど関係なさそう

  • 行本体を読まなければいけない(=カバリングインデックスで済まない)select_lsitになるとサロゲートキーの充填数の差は目立たなくなる

  • ナチュラルキーの左端でレンジスキャンする時がページ読み取り数は最小
  • 読みだすページの数だけで比べると , セカンダリキー引きはテーブルスキャンよりも読むページ数は多いことがある

Viewing all articles
Browse latest Browse all 581

Trending Articles