浏览代码

perf(database): index enclosure URL digest as bytea instead of hex

The enclosures_user_entry_url_unique_idx expression index stored the URL
digest as encode(sha256(url::bytea), 'hex'), a 64-byte hex text encoding
of a 32-byte value. Index the raw sha256(url::bytea) bytea instead to
roughly halve the index on disk, and update the matching ON CONFLICT
clause in createEnclosure so its inference still resolves to the index.

On 150k enclosures the index shrank from 27 MB to 11 MB (~59%).
jvoisin 1 月之前
父节点
当前提交
a84533db6c
共有 2 个文件被更改,包括 12 次插入 和 1 次删除
  1. 11 0
      internal/database/migrations.go
  2. 1 1
      internal/storage/enclosure.go

+ 11 - 0
internal/database/migrations.go

@@ -1568,4 +1568,15 @@ var migrations = [...]func(tx *sql.Tx) error{
 		`)
 		return err
 	},
+	func(tx *sql.Tx) (err error) {
+		// Index the raw SHA-256 digest (32 bytes) instead of its hex text
+		// encoding (64 bytes) to roughly halve this index on disk. The
+		// ON CONFLICT clause in createEnclosure uses the same expression.
+		_, err = tx.Exec(`
+			DROP INDEX IF EXISTS enclosures_user_entry_url_unique_idx;
+			CREATE UNIQUE INDEX enclosures_user_entry_url_unique_idx
+				ON enclosures (user_id, entry_id, sha256(url::bytea));
+		`)
+		return err
+	},
 }

+ 1 - 1
internal/storage/enclosure.go

@@ -157,7 +157,7 @@ func (s *Storage) createEnclosure(tx *sql.Tx, enclosure *model.Enclosure) error
 			(url, size, mime_type, entry_id, user_id, media_progression)
 		VALUES
 			($1, $2, $3, $4, $5, $6)
-		ON CONFLICT (user_id, entry_id, encode(sha256(url::bytea), 'hex')) DO NOTHING
+		ON CONFLICT (user_id, entry_id, sha256(url::bytea)) DO NOTHING
 		RETURNING
 			id
 	`