基本上我需要一个适合查询的数据库,比如LIKE %abc%
.
我已经尝试过使用 GIN 索引的 PostgreSQL,它非常好,但也许还有更好的东西?我还尝试了 MongoDB,发现像“/abc/”这样的查询工作得非常糟糕,而 Mongo 索引只支持“/^abc/”。
我的数据库结构非常简单。
PostgreSQL 中的示例查询:
SELECT DISTINCT(id), title FROM data AS data
INNER JOIN datatosynonym AS dts ON dts.data_id = data.id
WHERE dts.synonym_simple LIKE "%abc%"
在 MongoDB 中
db.data.find({synonymssimple: /abc/})
其中 synonymssimple 是一个字符串数组。
PostgreSQL 中的示例数据
数据表:
id | title | timestamp
1 | Abc | 1145836800
2 | Qwe | 1145836800
数据同义词表:
id | synonym_simple | data_id
1 | abc | 1
2 | bac | 1
我的基准测试显示以下结果:
- 具有 b-tree 索引和 %abc% 查询的 PostgreSQL - 每个查询约 15 毫秒
- 具有 b-tree 索引和 abc% 查询的 PostgreSQL - 每个查询约 1ms
- 具有 GIN 索引和 %abc% 查询的 PostgreSQL - 每个查询约 1.5 毫秒
- 具有 GIN 索引和 abc% 查询的 PostgreSQL - 每个查询约 1 毫秒
- 没有索引和 /abc/ 查询的 MongoDB - 每个查询约 25 毫秒
- 具有 b-tree 索引和 /abc/ 查询的 MongoDB - 每个查询约 80 毫秒
- 具有 b-tree 索引和 /^abc/ 查询的 MongoDB - 每个查询约 0.25 毫秒
遗憾的是我不能使用 /^abc/ 查询。
一种技术是将“未锚定”查询拆分为两个“锚定”部分。
正如您所展示的,带有尾随通配符的 B-Tree 搜索速度很快。问题是您还需要一个前导通配符。如果您可以将前导通配符变成尾随通配符,那就太好了。REVERSE函数将在此处提供帮助。查询变为
为了有效,必须在反转文本上有一个索引。这是写入时的开销,并且会使用额外的存储空间。等到读取时间将需要扫描数据,这反而违背了目的。除其他外,请参阅此处的示例。