[{"data":1,"prerenderedAt":811},["ShallowReactive",2],{"content-/db-slow-response-debug":3,"all-pages-for-dir":788,"related-/db-slow-response-debug":789,"og-image-/db-slow-response-debug":810},{"id":4,"title":5,"body":6,"category":774,"concepts":774,"description":775,"extension":776,"meta":777,"navigation":57,"ogImage":774,"path":778,"project_name":774,"published":779,"publishedAt":780,"seo":781,"source":774,"stem":782,"tags":783,"todo":774,"unpublished":779,"updatedAt":780,"__hash__":787},"pages/2025-12/2025-12-19/db-slow-response-debug.md","DBのレスポンスが遅い時の調査方法",{"type":7,"value":8,"toc":760},"minimark",[9,13,17,26,152,155,158,161,204,215,230,234,237,309,312,376,379,384,443,447,450,486,490,539,542,546,549,582,586,674,677,680,684,692,695,700,726,731,748,753,756],[10,11,5],"h1",{"id":12},"dbのレスポンスが遅い時の調査方法",[14,15,16],"h2",{"id":16},"まず切り分け",[18,19,20,21,25],"p",{},"「DBが遅い」と言われたら、最初にやるのは",[22,23,24],"strong",{},"本当にDBが遅いのか","という確認である。",[27,28,33],"pre",{"className":29,"code":30,"language":31,"meta":32,"style":32},"language-sql shiki shiki-themes vitesse-light vitesse-light","-- 現在実行中のクエリを確認（MySQL）\nSHOW PROCESSLIST;\n\n-- PostgreSQLなら\nSELECT pid, now() - pg_stat_activity.query_start AS duration, query, state\nFROM pg_stat_activity\nWHERE state != 'idle'\nORDER BY duration DESC;\n","sql","",[34,35,36,45,52,59,65,105,114,137],"code",{"__ignoreMap":32},[37,38,41],"span",{"class":39,"line":40},"line",1,[37,42,44],{"class":43},"sxvE3","-- 現在実行中のクエリを確認（MySQL）\n",[37,46,48],{"class":39,"line":47},2,[37,49,51],{"class":50},"sG7-3","SHOW PROCESSLIST;\n",[37,53,55],{"class":39,"line":54},3,[37,56,58],{"emptyLinePlaceholder":57},true,"\n",[37,60,62],{"class":39,"line":61},4,[37,63,64],{"class":43},"-- PostgreSQLなら\n",[37,66,68,72,75,78,82,86,90,93,96,99,102],{"class":39,"line":67},5,[37,69,71],{"class":70},"sHkkW","SELECT",[37,73,74],{"class":50}," pid, ",[37,76,77],{"class":70},"now",[37,79,81],{"class":80},"shFtX","()",[37,83,85],{"class":84},"stQ0i"," -",[37,87,89],{"class":88},"snbK4"," pg_stat_activity",[37,91,92],{"class":50},".",[37,94,95],{"class":88},"query_start",[37,97,98],{"class":70}," AS",[37,100,101],{"class":50}," duration, query, ",[37,103,104],{"class":70},"state\n",[37,106,108,111],{"class":39,"line":107},6,[37,109,110],{"class":70},"FROM",[37,112,113],{"class":50}," pg_stat_activity\n",[37,115,117,120,123,126,130,134],{"class":39,"line":116},7,[37,118,119],{"class":70},"WHERE",[37,121,122],{"class":70}," state",[37,124,125],{"class":84}," !=",[37,127,129],{"class":128},"sMJiu"," '",[37,131,133],{"class":132},"sdGka","idle",[37,135,136],{"class":128},"'\n",[37,138,140,143,146,149],{"class":39,"line":139},8,[37,141,142],{"class":70},"ORDER BY",[37,144,145],{"class":50}," duration ",[37,147,148],{"class":70},"DESC",[37,150,151],{"class":50},";\n",[18,153,154],{},"長時間走っているクエリがあれば、そいつが犯人候補である。なければアプリ側のコネクションプールの枯渇とか、ネットワークレイテンシを疑う。",[14,156,157],{"id":157},"スロークエリログを見る",[18,159,160],{},"本番環境なら、大抵有効化されているはずである。",[27,162,164],{"className":29,"code":163,"language":31,"meta":32,"style":32},"-- MySQL: スロークエリの設定確認\nSHOW VARIABLES LIKE 'slow_query%';\nSHOW VARIABLES LIKE 'long_query_time';\n",[34,165,166,171,189],{"__ignoreMap":32},[37,167,168],{"class":39,"line":40},[37,169,170],{"class":43},"-- MySQL: スロークエリの設定確認\n",[37,172,173,176,179,181,184,187],{"class":39,"line":47},[37,174,175],{"class":50},"SHOW VARIABLES ",[37,177,178],{"class":70},"LIKE",[37,180,129],{"class":128},[37,182,183],{"class":132},"slow_query%",[37,185,186],{"class":128},"'",[37,188,151],{"class":50},[37,190,191,193,195,197,200,202],{"class":39,"line":54},[37,192,175],{"class":50},[37,194,178],{"class":70},[37,196,129],{"class":128},[37,198,199],{"class":132},"long_query_time",[37,201,186],{"class":128},[37,203,151],{"class":50},[18,205,206,207,210,211,214],{},"ログの場所は",[34,208,209],{},"/var/log/mysql/slow.log","あたりである。",[34,212,213],{},"pt-query-digest","で集計すると、どのクエリが何回呼ばれて合計何秒食っているか一発でわかる。",[27,216,220],{"className":217,"code":218,"language":219,"meta":32,"style":32},"language-bash shiki shiki-themes vitesse-light vitesse-light","pt-query-digest /var/log/mysql/slow.log\n","bash",[34,221,222],{"__ignoreMap":32},[37,223,224,227],{"class":39,"line":40},[37,225,213],{"class":226},"senZ8",[37,228,229],{"class":132}," /var/log/mysql/slow.log\n",[14,231,233],{"id":232},"explain-で実行計画を見る","EXPLAIN で実行計画を見る",[18,235,236],{},"問題のクエリを特定したらEXPLAINで実行計画を見る。",[27,238,240],{"className":29,"code":239,"language":31,"meta":32,"style":32},"EXPLAIN SELECT * FROM orders\nWHERE user_id = 123\nAND created_at > '2024-01-01'\nORDER BY created_at DESC\nLIMIT 100;\n",[34,241,242,258,272,290,299],{"__ignoreMap":32},[37,243,244,247,249,252,255],{"class":39,"line":40},[37,245,246],{"class":50},"EXPLAIN ",[37,248,71],{"class":70},[37,250,251],{"class":84}," *",[37,253,254],{"class":70}," FROM",[37,256,257],{"class":50}," orders\n",[37,259,260,262,265,268],{"class":39,"line":47},[37,261,119],{"class":70},[37,263,264],{"class":50}," user_id ",[37,266,267],{"class":84},"=",[37,269,271],{"class":270},"sM54T"," 123\n",[37,273,274,277,280,283,285,288],{"class":39,"line":54},[37,275,276],{"class":70},"AND",[37,278,279],{"class":50}," created_at ",[37,281,282],{"class":84},">",[37,284,129],{"class":128},[37,286,287],{"class":132},"2024-01-01",[37,289,136],{"class":128},[37,291,292,294,296],{"class":39,"line":61},[37,293,142],{"class":70},[37,295,279],{"class":50},[37,297,298],{"class":70},"DESC\n",[37,300,301,304,307],{"class":39,"line":67},[37,302,303],{"class":70},"LIMIT",[37,305,306],{"class":270}," 100",[37,308,151],{"class":50},[18,310,311],{},"見るべきポイント：",[313,314,315,328],"table",{},[316,317,318],"thead",{},[319,320,321,325],"tr",{},[322,323,324],"th",{},"項目",[322,326,327],{},"ヤバいパターン",[329,330,331,343,351,365],"tbody",{},[319,332,333,337],{},[334,335,336],"td",{},"type",[334,338,339,342],{},[34,340,341],{},"ALL","（フルスキャン）",[319,344,345,348],{},[334,346,347],{},"rows",[334,349,350],{},"想定より桁違いに多い",[319,352,353,356],{},[334,354,355],{},"Extra",[334,357,358,361,362],{},[34,359,360],{},"Using filesort",", ",[34,363,364],{},"Using temporary",[319,366,367,370],{},[334,368,369],{},"key",[334,371,372,375],{},[34,373,374],{},"NULL","（インデックス使われてない）",[14,377,378],{"id":378},"よくある原因と対処",[380,381,383],"h3",{"id":382},"_1-インデックスが効いてない","1. インデックスが効いてない",[27,385,387],{"className":29,"code":386,"language":31,"meta":32,"style":32},"-- インデックスの確認\nSHOW INDEX FROM orders;\n\n-- 複合インデックスの順序が重要\n-- WHERE user_id = ? AND created_at > ? なら\nCREATE INDEX idx_user_created ON orders(user_id, created_at);\n-- user_id が先。選択性の高い方を先に。\n",[34,388,389,394,407,411,416,421,438],{"__ignoreMap":32},[37,390,391],{"class":39,"line":40},[37,392,393],{"class":43},"-- インデックスの確認\n",[37,395,396,399,402,404],{"class":39,"line":47},[37,397,398],{"class":50},"SHOW ",[37,400,401],{"class":70},"INDEX",[37,403,254],{"class":70},[37,405,406],{"class":50}," orders;\n",[37,408,409],{"class":39,"line":54},[37,410,58],{"emptyLinePlaceholder":57},[37,412,413],{"class":39,"line":61},[37,414,415],{"class":43},"-- 複合インデックスの順序が重要\n",[37,417,418],{"class":39,"line":67},[37,419,420],{"class":43},"-- WHERE user_id = ? AND created_at > ? なら\n",[37,422,423,426,429,432,435],{"class":39,"line":107},[37,424,425],{"class":70},"CREATE",[37,427,428],{"class":70}," INDEX",[37,430,431],{"class":226}," idx_user_created",[37,433,434],{"class":70}," ON",[37,436,437],{"class":50}," orders(user_id, created_at);\n",[37,439,440],{"class":39,"line":116},[37,441,442],{"class":43},"-- user_id が先。選択性の高い方を先に。\n",[380,444,446],{"id":445},"_2-n1問題","2. N+1問題",[18,448,449],{},"アプリ側のログで同じクエリが大量に流れていたらこれである。ORMのeager loadingで解決する。",[27,451,455],{"className":452,"code":453,"language":454,"meta":32,"style":32},"language-ruby shiki shiki-themes vitesse-light vitesse-light","# Rails の例\n# Bad: N+1\nUser.all.each { |u| u.posts }\n\n# Good: eager load\nUser.includes(:posts).each { |u| u.posts }\n","ruby",[34,456,457,462,467,472,476,481],{"__ignoreMap":32},[37,458,459],{"class":39,"line":40},[37,460,461],{},"# Rails の例\n",[37,463,464],{"class":39,"line":47},[37,465,466],{},"# Bad: N+1\n",[37,468,469],{"class":39,"line":54},[37,470,471],{},"User.all.each { |u| u.posts }\n",[37,473,474],{"class":39,"line":61},[37,475,58],{"emptyLinePlaceholder":57},[37,477,478],{"class":39,"line":67},[37,479,480],{},"# Good: eager load\n",[37,482,483],{"class":39,"line":107},[37,484,485],{},"User.includes(:posts).each { |u| u.posts }\n",[380,487,489],{"id":488},"_3-ロック待ち","3. ロック待ち",[27,491,493],{"className":29,"code":492,"language":31,"meta":32,"style":32},"-- MySQL: ロック状況の確認\nSHOW ENGINE INNODB STATUS\\G\n\n-- PostgreSQL\nSELECT * FROM pg_locks WHERE NOT granted;\n",[34,494,495,500,511,515,520],{"__ignoreMap":32},[37,496,497],{"class":39,"line":40},[37,498,499],{"class":43},"-- MySQL: ロック状況の確認\n",[37,501,502,505,508],{"class":39,"line":47},[37,503,504],{"class":50},"SHOW ENGINE INNODB ",[37,506,507],{"class":70},"STATUS",[37,509,510],{"class":50},"\\G\n",[37,512,513],{"class":39,"line":54},[37,514,58],{"emptyLinePlaceholder":57},[37,516,517],{"class":39,"line":61},[37,518,519],{"class":43},"-- PostgreSQL\n",[37,521,522,524,526,528,531,533,536],{"class":39,"line":67},[37,523,71],{"class":70},[37,525,251],{"class":84},[37,527,254],{"class":70},[37,529,530],{"class":50}," pg_locks ",[37,532,119],{"class":70},[37,534,535],{"class":70}," NOT",[37,537,538],{"class":50}," granted;\n",[18,540,541],{},"長時間トランザクションが開きっぱなしとか、デッドロックとかが原因である。アプリ側でトランザクションの粒度を見直す。",[380,543,545],{"id":544},"_4-統計情報が古い","4. 統計情報が古い",[18,547,548],{},"古い統計情報を元に、オプティマイザが変な実行計画を選んでいることがある。",[27,550,552],{"className":29,"code":551,"language":31,"meta":32,"style":32},"-- MySQL\nANALYZE TABLE orders;\n\n-- PostgreSQL\nANALYZE orders;\n",[34,553,554,559,569,573,577],{"__ignoreMap":32},[37,555,556],{"class":39,"line":40},[37,557,558],{"class":43},"-- MySQL\n",[37,560,561,564,567],{"class":39,"line":47},[37,562,563],{"class":50},"ANALYZE ",[37,565,566],{"class":70},"TABLE",[37,568,406],{"class":50},[37,570,571],{"class":39,"line":54},[37,572,58],{"emptyLinePlaceholder":57},[37,574,575],{"class":39,"line":61},[37,576,519],{"class":43},[37,578,579],{"class":39,"line":67},[37,580,581],{"class":50},"ANALYZE orders;\n",[380,583,585],{"id":584},"_5-バッファプールshared_buffers-が足りない","5. バッファプール/shared_buffers が足りない",[27,587,589],{"className":29,"code":588,"language":31,"meta":32,"style":32},"-- MySQL: バッファプールのヒット率\nSHOW STATUS LIKE 'Innodb_buffer_pool_read%';\n-- read_requests に対して reads が多いとディスクI/Oが多い\n\n-- PostgreSQL\nSELECT\n  sum(heap_blks_hit) / (sum(heap_blks_hit) + sum(heap_blks_read)) as hit_ratio\nFROM pg_statio_user_tables;\n",[34,590,591,596,614,619,623,627,632,667],{"__ignoreMap":32},[37,592,593],{"class":39,"line":40},[37,594,595],{"class":43},"-- MySQL: バッファプールのヒット率\n",[37,597,598,600,602,605,607,610,612],{"class":39,"line":47},[37,599,398],{"class":50},[37,601,507],{"class":70},[37,603,604],{"class":70}," LIKE",[37,606,129],{"class":128},[37,608,609],{"class":132},"Innodb_buffer_pool_read%",[37,611,186],{"class":128},[37,613,151],{"class":50},[37,615,616],{"class":39,"line":54},[37,617,618],{"class":43},"-- read_requests に対して reads が多いとディスクI/Oが多い\n",[37,620,621],{"class":39,"line":61},[37,622,58],{"emptyLinePlaceholder":57},[37,624,625],{"class":39,"line":67},[37,626,519],{"class":43},[37,628,629],{"class":39,"line":107},[37,630,631],{"class":70},"SELECT\n",[37,633,634,638,641,644,647,650,652,655,658,661,664],{"class":39,"line":116},[37,635,637],{"class":636},"sz8Xr","  sum",[37,639,640],{"class":50},"(heap_blks_hit) ",[37,642,643],{"class":84},"/",[37,645,646],{"class":50}," (",[37,648,649],{"class":636},"sum",[37,651,640],{"class":50},[37,653,654],{"class":84},"+",[37,656,657],{"class":636}," sum",[37,659,660],{"class":50},"(heap_blks_read)) ",[37,662,663],{"class":70},"as",[37,665,666],{"class":50}," hit_ratio\n",[37,668,669,671],{"class":39,"line":139},[37,670,110],{"class":70},[37,672,673],{"class":50}," pg_statio_user_tables;\n",[18,675,676],{},"ヒット率が95%を切っていたら、メモリを増やすことを検討する。",[14,678,679],{"id":679},"調査の流れまとめ",[681,682],"drawio-viewer",{"src":683},"/2025-12-19/db-debug-flow.drawio",[27,685,690],{"className":686,"code":688,"language":689},[687],"language-text","1. SHOW PROCESSLIST で現在の状況確認\n     ↓\n2. スロークエリログで犯人特定\n     ↓\n3. EXPLAIN で実行計画確認\n     ↓\n4. インデックス追加 or クエリ書き換え or 設定チューニング\n     ↓\n5. 効果測定\n","text",[34,691,688],{"__ignoreMap":32},[14,693,694],{"id":694},"面接で聞かれがちな追加質問",[18,696,697],{},[22,698,699],{},"「インデックス張ったのに効かないケースは？」",[701,702,703,707,714,717,723],"ul",{},[704,705,706],"li",{},"カーディナリティが低い（性別とか）",[704,708,709,710,713],{},"関数を使ってる（",[34,711,712],{},"WHERE YEAR(created_at) = 2024","）",[704,715,716],{},"型の暗黙変換（文字列カラムに数値で検索）",[704,718,719,720,713],{},"LIKE の前方一致以外（",[34,721,722],{},"LIKE '%keyword'",[704,724,725],{},"OR 条件で片方にインデックスがない",[18,727,728],{},[22,729,730],{},"「本番で急に遅くなった原因として何を疑う？」",[701,732,733,736,739,742,745],{},[704,734,735],{},"データ量の増加で実行計画が変わった",[704,737,738],{},"統計情報の自動更新タイミング",[704,740,741],{},"ロック競合の増加",[704,743,744],{},"ディスクI/Oの飽和（他のバッチ処理と競合など）",[704,746,747],{},"コネクションプールの枯渇",[18,749,750],{},[22,751,752],{},"「読み取りと書き込みどっちが遅い？」",[18,754,755],{},"切り分けが重要である。書き込みが遅いならレプリケーション遅延やディスクI/Oを疑う。読み取りだけが遅いならインデックスかキャッシュの問題である。",[757,758,759],"style",{},"html pre.shiki code .sxvE3, html code.shiki .sxvE3{--shiki-default:#A0ADA0;--shiki-dark:#A0ADA0}html pre.shiki code .sG7-3, html code.shiki .sG7-3{--shiki-default:#393A34;--shiki-dark:#393A34}html pre.shiki code .sHkkW, html code.shiki .sHkkW{--shiki-default:#1E754F;--shiki-dark:#1E754F}html pre.shiki code .shFtX, html code.shiki .shFtX{--shiki-default:#999999;--shiki-dark:#999999}html pre.shiki code .stQ0i, html code.shiki .stQ0i{--shiki-default:#AB5959;--shiki-dark:#AB5959}html pre.shiki code .snbK4, html code.shiki .snbK4{--shiki-default:#A65E2B;--shiki-dark:#A65E2B}html pre.shiki code .sMJiu, html code.shiki .sMJiu{--shiki-default:#B5695977;--shiki-dark:#B5695977}html pre.shiki code .sdGka, html code.shiki .sdGka{--shiki-default:#B56959;--shiki-dark:#B56959}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .senZ8, html code.shiki .senZ8{--shiki-default:#59873A;--shiki-dark:#59873A}html pre.shiki code .sM54T, html code.shiki .sM54T{--shiki-default:#2F798A;--shiki-dark:#2F798A}html pre.shiki code .sz8Xr, html code.shiki .sz8Xr{--shiki-default:#998418;--shiki-dark:#998418}",{"title":32,"searchDepth":47,"depth":47,"links":761},[762,763,764,765,772,773],{"id":16,"depth":47,"text":16},{"id":157,"depth":47,"text":157},{"id":232,"depth":47,"text":233},{"id":378,"depth":47,"text":378,"children":766},[767,768,769,770,771],{"id":382,"depth":54,"text":383},{"id":445,"depth":54,"text":446},{"id":488,"depth":54,"text":489},{"id":544,"depth":54,"text":545},{"id":584,"depth":54,"text":585},{"id":679,"depth":47,"text":679},{"id":694,"depth":47,"text":694},null,"データベースのパフォーマンス問題を特定・解決するためのアプローチ","md",{},"/db-slow-response-debug",false,"2025-12-19T00:00:00.000Z",{"title":5,"description":775},"2025-12/2025-12-19/db-slow-response-debug",[784,785,786],"database","performance","debugging","FO2PMYkZtkNuY8BuapXASO9AUaYXRyqsYM_F3UmQGP0",[],[790,794,798,802,806],{"title":791,"path":792,"publishedAt":793},"AZNだけ「No data」になる原因調査メモ","/azn-no-data-investigation","2025-12-15T00:00:00.000Z",{"title":795,"path":796,"publishedAt":797},"eurekapu-nuxt4: Drizzle ORM移行計画 -- 4並行エージェント調査からCodexレビューまで","/drizzle-orm-migration-2026-02-23","2026-02-23T00:00:00.000Z",{"title":799,"path":800,"publishedAt":801},"検索ページ（/search）パフォーマンス改善計画","/search-page-performance-plan","2026-01-29T00:00:00.000Z",{"title":803,"path":804,"publishedAt":805},"勘定科目マスターDB化の実装記録","/account-master-db-implementation","2026-01-26T00:00:00.000Z",{"title":807,"path":808,"publishedAt":809},"Nuxt 4 + @nuxt/content の開発サーバー起動が遅い原因と対策","/nuxt-dev-startup-time","2026-01-10T00:00:00.000Z","https://log.eurekapu.com/og/blog/db-slow-response-debug.png?v=2025-12-19T00%3A00%3A00.000Z&title=DB%E3%81%AE%E3%83%AC%E3%82%B9%E3%83%9D%E3%83%B3%E3%82%B9%E3%81%8C%E9%81%85%E3%81%84%E6%99%82%E3%81%AE%E8%AA%BF%E6%9F%BB%E6%96%B9%E6%B3%95&author=Kei%20Komatsu&sig=1fd875ea796b75a6",1785654979025]