Reuse prepared statement for follow distance insertsUnverified
0b50627 parent: 0ba006b modified
internal/cluster/social.go +9 -6 | @@ -18,7 +18,7 @@ func chunk[T any](s []T, size int) [][]T { | ||
| 18 | 18 | return chunks |
| 19 | 19 | } |
| 20 | 20 | |
| 21 | -func (e *Engine) writeFollowDistancesForUser(ctx context.Context, tx *sql.Tx, src string) (int, error) { | |
| 21 | +func (e *Engine) writeFollowDistancesForUser(ctx context.Context, stmt *sql.Stmt, src string) (int, error) { | |
| 22 | 22 | reachable, err := e.bfsReachable(ctx, src) |
| 23 | 23 | if err != nil { |
| 24 | 24 | return 0, err |
| @@ -27,10 +27,7 @@ func (e *Engine) writeFollowDistancesForUser(ctx context.Context, tx *sql.Tx, sr | ||
| 27 | 27 | written := 0 |
| 28 | 28 | for dst, d := range reachable { |
| 29 | 29 | if d > 0 { |
| 30 | - if _, err := tx.ExecContext(ctx, | |
| 31 | - `INSERT INTO recs.follow_distances (user_a, user_b, distance) VALUES (?, ?, ?)`, | |
| 32 | - src, dst, d, | |
| 33 | - ); err != nil { | |
| 30 | + if _, err := stmt.ExecContext(ctx, src, dst, d); err != nil { | |
| 34 | 31 | return written, err |
| 35 | 32 | } |
| 36 | 33 | written++ |
| @@ -127,8 +124,14 @@ func (e *Engine) ComputeFollowDistances(ctx context.Context) error { | ||
| 127 | 124 | } |
| 128 | 125 | |
| 129 | 126 | var totalPairs int |
| 127 | + stmt, err := tx.PrepareContext(ctx, `INSERT INTO recs.follow_distances (user_a, user_b, distance) VALUES (?, ?, ?)`) | |
| 128 | + if err != nil { | |
| 129 | + return err | |
| 130 | + } | |
| 131 | + defer stmt.Close() | |
| 132 | + | |
| 130 | 133 | for _, did := range dirtyUsers { |
| 131 | - n, err := e.writeFollowDistancesForUser(ctx, tx, did) | |
| 134 | + n, err := e.writeFollowDistancesForUser(ctx, stmt, did) | |
| 132 | 135 | if err != nil { |
| 133 | 136 | return err |
| 134 | 137 | } |
| @@ -18,7 +18,7 @@ func chunk[T any](s []T, size int) [][]T { | |||
| 18 | return chunks | 18 | return chunks |
| 19 | } | 19 | } |
| 20 | 20 | ||
| 21 | -func (e *Engine) writeFollowDistancesForUser(ctx context.Context, tx *sql.Tx, src string) (int, error) { | 21 | +func (e *Engine) writeFollowDistancesForUser(ctx context.Context, stmt *sql.Stmt, src string) (int, error) { |
| 22 | reachable, err := e.bfsReachable(ctx, src) | 22 | reachable, err := e.bfsReachable(ctx, src) |
| 23 | if err != nil { | 23 | if err != nil { |
| 24 | return 0, err | 24 | return 0, err |
| @@ -27,10 +27,7 @@ func (e *Engine) writeFollowDistancesForUser(ctx context.Context, tx *sql.Tx, sr | |||
| 27 | written := 0 | 27 | written := 0 |
| 28 | for dst, d := range reachable { | 28 | for dst, d := range reachable { |
| 29 | if d > 0 { | 29 | if d > 0 { |
| 30 | - if _, err := tx.ExecContext(ctx, | 30 | + if _, err := stmt.ExecContext(ctx, src, dst, d); err != nil { |
| 31 | - `INSERT INTO recs.follow_distances (user_a, user_b, distance) VALUES (?, ?, ?)`, | ||
| 32 | - src, dst, d, | ||
| 33 | - ); err != nil { | ||
| 34 | return written, err | 31 | return written, err |
| 35 | } | 32 | } |
| 36 | written++ | 33 | written++ |
| @@ -127,8 +124,14 @@ func (e *Engine) ComputeFollowDistances(ctx context.Context) error { | |||
| 127 | } | 124 | } |
| 128 | 125 | ||
| 129 | var totalPairs int | 126 | var totalPairs int |
| 127 | + stmt, err := tx.PrepareContext(ctx, `INSERT INTO recs.follow_distances (user_a, user_b, distance) VALUES (?, ?, ?)`) | ||
| 128 | + if err != nil { | ||
| 129 | + return err | ||
| 130 | + } | ||
| 131 | + defer stmt.Close() | ||
| 132 | + | ||
| 130 | for _, did := range dirtyUsers { | 133 | for _, did := range dirtyUsers { |
| 131 | - n, err := e.writeFollowDistancesForUser(ctx, tx, did) | 134 | + n, err := e.writeFollowDistancesForUser(ctx, stmt, did) |
| 132 | if err != nil { | 135 | if err != nil { |
| 133 | return err | 136 | return err |
| 134 | } | 137 | } |