基于Spring Reactive与PostgreSQL的超大规模哈希库查询提速咨询
PostgreSQL 8亿+哈希数据查询性能优化求助
背景与需求
- 数据库:PostgreSQL,存储800,000,000+条哈希记录
- 查询流程:
- 客户端输入字符串
- 服务器将字符串通过SHA-1算法转换为哈希值
- 在表中查询匹配该哈希值的记录
当前实现与问题
基础SQL与索引配置
查询SQL语句:
SELECT table_source.id FROM base_source WHERE table_source.str_source_sha1 = '01B3773A12C0ED01767870001574FF002342F7521E';
已为查询字段创建索引:
CREATE INDEX IF NOT EXISTS encoded_index ON table_source (str_source_sha1);
不同查询方式的耗时对比
- IntelliJ数据库客户端直接查询:
- 查询存在的记录(id=600735221):耗时164ms(执行129ms,获取35ms),连续查询因缓存耗时略有降低
- 查询不存在的记录:耗时62ms(执行15ms,获取47ms)
- Spring Reactive内存过滤(已废弃):
以下代码通过全表加载后在内存中过滤,耗时极长:
public Mono<Boolean> runCheckupStrInHash(ResultCheckupDto resultCheckupDto) { String strInPlainText = resultCheckupDto.getStr(); String shaAlgorithm = encodeToSHAService.generateIntoSHAAlgorithm(strInPlainText); return sourceRepository.findAll() .flatMap( strFromBase -> { boolean isExistsStr = strFromBase.equals(shaAlgorithm); if (isExistsStr) { return Mono.just(Boolean.TRUE); } return Mono.empty(); } ) .next() .switchIfEmpty(Mono.just(Boolean.FALSE)); }
- Spring Reactive调用数据库查询(当前使用):
以下代码将哈希生成与数据库查询逻辑分离,但耗时暴增:
public Mono<Boolean> isExistsStr(ResultCheckupDto resultCheckupDto) { long start = System.nanoTime(); return Mono.just(resultCheckupDto) .map(resultCheckupDto::getStr) .map(encodeToSHAService::generateIntoSHAAlgorithm) .flatMap(sourceRepository::existsByStrEncodedSha) .map(result -> { long end = System.nanoTime(); long timeProcessing = end - start; double seconds = timeProcessing / 1_000_000_000.0; log.info("\n request processing time (database request) (sek) : {} \n", seconds); return result; }); }
耗时情况:
- 查询存在的记录:超110秒
- 查询不存在的记录:超160秒
限制条件
数据库数据量达35GB+(含索引),Redis缓存并非合适方案,需将查询耗时降低10倍以上,寻求优化思路。
内容的提问来源于stack exchange,提问作者skyho
相关产品推荐
相关产品推荐

