ネタバレ
Posted by ブクログ
2021年06月17日
実務でもよく見かける例えば「効果の薄いIndex」「多すぎるJoin」「とりあえず削除フラグ」などを例にアンチパターンとその解消方法が紹介されていてとても良かった。
読みながら自分のアプリケーションで場合を考えなら読み進められた。
以下、自分がいいと思った箇所のメモを記載。
### 2章 失われ...続きを読むた事実
- 履歴が保存されていることは重要。トラブル対応時に欲しい情報が失われていないか、の観点で履歴の保存は行う
- 例えば、購入した時点の消費税率を、別テーブルで参照しているとき、消費税が変わると、過去にかった金額の消費税率がわからなくなり、返品を行った際に不整合が起きたりする。
- 例えば、配送状態を上書きする仕様にしている場合、過去に配送中だったのか、配送済みになったのか、キャンセルがあったかなどの事実がわからなくなってしまう。
### 3章 やりすぎたJoin
- Joinを多く行うと、テーブルスキャンをする量が指数関数的に多くなり、DBへの負荷も増大する
- 例えば10,000行と10,000行のテーブルのJoinでは100,000,000行のテーブルスキャンがされてしまう。(Indexが貼られていたらその限りではない)
- なのでJoinするテーブルは小さくしてからJoinすることが大事
- Joinには3種類ある
- Nested Loop Join(NLJ):1行ずつループして処理する
- Hash Join:1度に全件読み込んで処理する(MySQLではサポートされていない)
- Sort Merge Join:全件をソートして上から順に比較する(MySQLではサポートされていない
### 4章 効かないIndex
- Indexが効かない(使われない)ケース
- 検索結果が多い、全体の件数が少ない
- 10,000件のうち9,999件取り出す場合など、Indexの意味がない
- 検索結果が全体の20%未満のとき、総レコード数が数万レコード以上あるときに有効
- 条件にその列を使っていない
- where age + 10 > 20)では無理。 where age > 20 -10 ならできる
- カーディナリティの低い列に対する検索
- Men / Womenしかない場合などIndexは意味ない
- あいまな検索
- where like %keyword% はIndexが効かない。先頭文字がないのでIndexは無理
### 5章 フラグの闇
- とりあえず削除フラグとかは危険。テーブルに「状態」を持たせずに済むならそのほうがいい
- ユニーク制約が使えなくなる(emailをユニークにしたいが、退会済みユーザーとemailがかぶるなど)
- カーディナリティが低いが、検索時には状態を含めて検索する必要が出てきてクエリが遅くなる
- もしテーブルに状態をもたせるならば、、、
- 対象のテーブルが小さく、Indexが不要なこと
- そのテーブルが関連するテーブルの親になることがなく、データ取得の際に頻繁にJoinの対象にならないこと
- Unique制約が不要で、外部キーでデータの整合性を担保する必要がない
### 6章 ソートの依存
RDBMSのエグゼキュータの評価順
1. FROM
2. ON
3. JOIN
4. WHERE
5. GROUP BY
6. HAVING
7. SELECT
8. DISTINCT
9. ORDER BY
10. LIMIT
- ページネーションでOffset100,000とかにすると結局100,000件のデータを見ている。where id > 100000 and みたいにするほうがい
### 9章 強すぎる制約
- 強すぎる制約をかけてそれを変更したくなったとき、Alter文での変更などになるがロックがかかりデータ量によっては結構な時間になるので、メンテナンスの時間を設ける必要もでてくる
- ビジネスロジックに伴う制約は変更される可能性があるので、アプリケーション側でのバリデーションにしたほうがいい
### 10章 ころんだあとのバックアップ
- 毎日バックアップをとっているが、いざ必要になったときにリストアしてみたらリストアできなかったみたいなこともある。バックアップが動いていること、バックアップでリストアできることなどもテストしておくといい。
### 11章 見られないエラーログ
- エラーログが出ていない、エラーが定常的にあって、重要なエラーが何か分からず放置されていることもよくある