N 1問題対策 - HirokiYoshida837/ISUCON2022 GitHub Wiki
N+1問題対策
1. INNER JOINで一括取得できないか
Inner Joinで一撃で取得。 取得する用の構造体を作らないといけない場合もある。
2. 1+1にできないか (別クエリによるプリロード)
for文内での1つずつのデータ取得を、IN句やNamedExec、sqlx.Inを使ってリストとして取れないかを検討する。
sqlx.Inを使うサンプル
query,param, err := sqlx.In(
"SELECT * FROM `users` WHERE `id` IN (?)",
ids,
)
// named query with a struct
p := Place{Country: "South Africa"}
rows, err := db.NamedQuery(`SELECT * FROM place WHERE country=:country`, p)
// named query with a map
m := map[string]interface{}{"city": "Johannesburg"}
result, err := db.NamedExec(`SELECT * FROM place WHERE city=:city`, m)
3. キャッシュからの参照にできないか
N回のクエリを発行する対象をインメモリキャッシュやmemcached、redisなどに入れておいて、 DBではなくキャッシュに対してN回、取得リクエストを実行する。