PostgreSQL 9.3.4 文档 | ||||
---|---|---|---|---|
Prev | Up | Chapter 12. 全文搜索 | Next |
有两种索引可以被用来加速全文搜索。注意全文搜索并非一定需要索引,但是在一个定期会被搜索的列上,通常需要有一个索引。
创建一个基于 GiST(通用搜索树)的索引。column可以是tsvector或tsquery类型。
创建一个基于 GIN(通用倒排索引)的索引。column必须是tsvector类型。
在两种索引类型之间有本质的性能区别,因此有必要理解它们的特性。
一个 GiST 索引是有损的,这表示索引可能产生假匹配,并且有必要检查真实的表行来消除这种假匹配(PostgreSQL在需要时会自动做这一步)。GiST 索引之所以是有损的,是因为每一个文档在索引中被表示为一个定长的签名。该签名通过哈希每一个词到一个 n 位串中的一个单一位来产生,通过将所有这些位 OR 在一起产生一个 n 位的文档签名。当两个词哈希到同一个位位置时就会产生假匹配。如果查询中所有词都有匹配(真或假),则必须检索表行查看匹配是否正确。
有损性导致的性能下降归因于不必要的表记录(即被证实为假匹配的记录)获取。因为表记录的随机访问是较慢的,这限制了 GiST 索引的可用性。假匹配的可能性取决于几个因素,特别是唯一词的数量,因此推荐使用词典来缩减这个数量。
GIN 索引对于标准查询不是有损的,但是它们的性能与唯一词的数量成对数关系(不过,GIN 索引只存储tsvector值的词(词位),而不存储它们的权重标签。这样一个当使用一个涉及到权重的查询时需要检查表行)。
在选择使用 GiST 还是 GIN 时,请考虑这些性能差异:
GIN 索引查找要比 GiST 快三倍
GIN 索引的构建时间是 GiST 的三倍
GIN 索引的更新要比 GiST 索引略慢,但是如果关掉快速更新支持(见Section 57.3.1) GIN 索引的更新要比 GiST 慢 十倍
GIN 索引的尺寸要比 GiST 索引大两到三倍
作为一个经验法则,GIN索引最适合静态数据,因为查找更快。对于动态数据,GiST 索引更新起来更快。特别地,如果唯一词(词位)的数量少于 100,000 个,GiST索引对于动态数据非常好并且快速,而GIN索引处理 100,000 个以上的词位更好但是更新起来更慢。
注意GIN索引的构件时间常常可以通过增加maintenance_work_mem来改进,而GiST索引的构建时间则与该参数无关。
对大集合分区并正确使用 GiST 和 GIN 索引允许实现带在线更新的快速搜索。分区可以在数据库层面上使用表继承来完成,或者是通过将文档分布在服务器上并使用dblink收集结果。后者是可能的,因为排名函数只使用本地信息。