stagingでEXPLAINまで確認しておいてこうなっちゃうのはもう不慮の事故としか言いようがないすね(インデックスショットガンへの反省という文脈とはいえ、狙いすましたインデックスでも起こり得る事故)
"「少しでも改善してくれれば」という気持ちで追加しました。遅いクエリに対して効くかもしれないインデックスを広めに貼る"ここがまさに事故の元
"根っこにあるのはMySQL 8.0 innodb_stats_methodのデフォルト値nulls_equalと、IS NULLに対するコスト計算の噛み合わせです。8.0系で現在も未修正のバグに類する挙動で、NULL多数カラムへの単独インデックスがトリガーになります"
とにかくインデックスを張れば何とか、みたいな根拠の薄い願望が原因だと思うのでいろいろよろしくない。お疲れさまでした。
MySQL が Null を全て同一の値として扱うところ、PostgreSQL ではどうだろう
わからんけど、なんでインデックス貼ったんだ?値が偏ることは自明だとしたら、有効的でないような?
ありそう。。
こういうの辛いな
MySQLでは単一のテーブル毎にひとつしかインデックスが使えないので、ほぼ全てのクエリで利用される癖にカーディナリティーの低い絞り込みにほとんど寄与しない単独インデックスを貼っておく事そのものがリスク
IS NULLの統計トラップ怖すぎ。EXPLAINが嘘をつく世界線は嫌だw
最近MYSQL使わないから同じこと起きそうで怖え。要注意
こわーーーーーー!!!ー!ー!
いつも思うけど、DBが勝手に最適なやり方を推論すること自体がかなり危うい仕様だと思うんだけど。実行計画も人間が書けるべきで、アーキテクチャが間違っている。DB作れないかなー
インデックスどれが最適かDBが選ぶのは本番環境だけ事故る要因の一つだと思う。とはいえ、まいかいインデックス指定するのもどうかと思うが…。
正常なデータがnullのものにインデックス貼ることはしないけど新人が手順だけ模倣して作業することを考えるならインデックスのレビューには本番データのカーディナリティを調べてつけるようにする。あと論理削除(ry
Oracle勢のSIerエンジニアは単一列のインデックスはNull見てくんない地雷だいたいみんな踏んでるから、そもそも複合インデックスにするか、削除済みは別テーブルに逃す設計にしそうな
これはやりそう。いろんな罠があるな……
インデックスって貼るものだったのか? 張るものだと思ってた。
PostgresSQLならINDEX idx_tickets(workspace_id) WHERE deleted_at IS NOT NULL と設定できるんだけどmysql辛いな。
実行計画への介入ができる仕組みがあるといいよね
MySQLはリスク(´・ω・`)
NULL多数カラム(deleted_at等)に単独INDEXを貼らない。nulls_equal統計でIS NULLのrows推定が1件に歪み、単独INDEXが最安と誤判定され全走査化。複合INDEXの後続に置く。stagingのEXPLAINは統計サンプリング次第で本番と逆転しうる。
解説パートがよかった
フラグにはビットマップインデックスじゃないの、でも効果少ないからなぁと思ったら、まったく別の話だった。人生の中で3か月くらい、ひたすらSQLとインデックスを調べていた時代があったので、いつか語ってみたい
めっちゃあり得るユースケースだな
自分もハマりそう… ステージングのデータをどう保つべきかみたいな話にもなるのかな
やはり postgres・・・postgres はすべてを解決する!(複数の単独インデックスを同時に使えるし、soft delete パターンに対しては部分インデックスも使えるし)
本文ちゃんと読んでないけど、カバリンクインデックスを複数張れないの?中々設計がシビアね。
deleted_atにインデックスを雑に貼ったら本番DBが死んだ
stagingでEXPLAINまで確認しておいてこうなっちゃうのはもう不慮の事故としか言いようがないすね(インデックスショットガンへの反省という文脈とはいえ、狙いすましたインデックスでも起こり得る事故)
"「少しでも改善してくれれば」という気持ちで追加しました。遅いクエリに対して効くかもしれないインデックスを広めに貼る"ここがまさに事故の元
"根っこにあるのはMySQL 8.0 innodb_stats_methodのデフォルト値nulls_equalと、IS NULLに対するコスト計算の噛み合わせです。8.0系で現在も未修正のバグに類する挙動で、NULL多数カラムへの単独インデックスがトリガーになります"
とにかくインデックスを張れば何とか、みたいな根拠の薄い願望が原因だと思うのでいろいろよろしくない。お疲れさまでした。
MySQL が Null を全て同一の値として扱うところ、PostgreSQL ではどうだろう
わからんけど、なんでインデックス貼ったんだ?値が偏ることは自明だとしたら、有効的でないような?
ありそう。。
こういうの辛いな
MySQLでは単一のテーブル毎にひとつしかインデックスが使えないので、ほぼ全てのクエリで利用される癖にカーディナリティーの低い絞り込みにほとんど寄与しない単独インデックスを貼っておく事そのものがリスク
IS NULLの統計トラップ怖すぎ。EXPLAINが嘘をつく世界線は嫌だw
最近MYSQL使わないから同じこと起きそうで怖え。要注意
こわーーーーーー!!!ー!ー!
いつも思うけど、DBが勝手に最適なやり方を推論すること自体がかなり危うい仕様だと思うんだけど。実行計画も人間が書けるべきで、アーキテクチャが間違っている。DB作れないかなー
インデックスどれが最適かDBが選ぶのは本番環境だけ事故る要因の一つだと思う。とはいえ、まいかいインデックス指定するのもどうかと思うが…。
正常なデータがnullのものにインデックス貼ることはしないけど新人が手順だけ模倣して作業することを考えるならインデックスのレビューには本番データのカーディナリティを調べてつけるようにする。あと論理削除(ry
Oracle勢のSIerエンジニアは単一列のインデックスはNull見てくんない地雷だいたいみんな踏んでるから、そもそも複合インデックスにするか、削除済みは別テーブルに逃す設計にしそうな
これはやりそう。いろんな罠があるな……
インデックスって貼るものだったのか? 張るものだと思ってた。
PostgresSQLならINDEX idx_tickets(workspace_id) WHERE deleted_at IS NOT NULL と設定できるんだけどmysql辛いな。
実行計画への介入ができる仕組みがあるといいよね
MySQLはリスク(´・ω・`)
NULL多数カラム(deleted_at等)に単独INDEXを貼らない。nulls_equal統計でIS NULLのrows推定が1件に歪み、単独INDEXが最安と誤判定され全走査化。複合INDEXの後続に置く。stagingのEXPLAINは統計サンプリング次第で本番と逆転しうる。
解説パートがよかった
フラグにはビットマップインデックスじゃないの、でも効果少ないからなぁと思ったら、まったく別の話だった。人生の中で3か月くらい、ひたすらSQLとインデックスを調べていた時代があったので、いつか語ってみたい
めっちゃあり得るユースケースだな
自分もハマりそう… ステージングのデータをどう保つべきかみたいな話にもなるのかな
やはり postgres・・・postgres はすべてを解決する!(複数の単独インデックスを同時に使えるし、soft delete パターンに対しては部分インデックスも使えるし)
本文ちゃんと読んでないけど、カバリンクインデックスを複数張れないの?中々設計がシビアね。