Django 全文索引与模式索引

Django 全文索引与模式索引,django,postgresql,indexing,django-queryset,full-text-indexing,Django,Postgresql,Indexing,Django Queryset,Full Text Indexing,我正在使用django,我所有的查询都是由django创建的,所以我没有手写查询 我有一个BillRecords表,其中有一个字段subscriberno。在我的django过滤器中,我使用了如下过滤查询: BillRecords.objects.filter(subscriberno__icontains='123456') SELECT "subscriberno" FROM "BillRecords" WHERE UPPER("subscriberno"::text) LIKE UPPE

我正在使用django,我所有的查询都是由django创建的,所以我没有手写查询

我有一个
BillRecords
表,其中有一个字段
subscriberno
。在我的django过滤器中,我使用了如下过滤查询:

BillRecords.objects.filter(subscriberno__icontains='123456')
SELECT "subscriberno" FROM "BillRecords" WHERE UPPER("subscriberno"::text) LIKE UPPER(E'%123456%');
因为客户说可能是实数的缩短版,
subscriberno

该过滤器输出如下查询:

BillRecords.objects.filter(subscriberno__icontains='123456')
SELECT "subscriberno" FROM "BillRecords" WHERE UPPER("subscriberno"::text) LIKE UPPER(E'%123456%');
subscriberno
是字符字段,因为有些数字包含字母和一些特殊字符

在我的数据库中,我的同事为该列创建了两个索引

"BillRecords_subscriberno" btree (subscriberno)
"BillRecords_fsubscriberno_like" btree (subscriberno varchar_pattern_ops)
我想知道对这样的查询使用两个索引是合乎逻辑的。因为我们所有的django过滤器都使用
icontains
,这应该是像我上面写的那样创建查询

Postgres对查询的分析如下:

Seq Scan on BillRecords  (cost=0.00..159782.40 rows=370 width=15) (actual time=579.637..3705.079 rows=10 loops=1)
Filter: (upper((subscriberno)::text) ~~ '%123456%'::text)
Total runtime: 3705.106 ms
(3 rows)
因此,据我所知,没有使用索引。由于索引usega在数据插入和更新方面有成本,所以有两个没有使用的索引(据我从这篇分析中所见)似乎不合逻辑

django是否有机会为类似的
icontanis
过滤器输出不同的查询?或者我的索引完全无用?

包含(子字符串)查询无法访问索引(除非运算符链接到全文模块)。另一方面,从查询开始可以从索引中获益。如果基数不太低,并且插入通常不是大批量进行的,而是在OLTP场景中进行的,则索引开销可以忽略不计

我是否正确地读取了统计数据:扫描370行几乎需要4秒


P.S.您可以考虑另一种方法:使用基于函数的索引,也许在订阅号的最后四个字符上,例如,订阅号的前三个字符,在搜索词bookend中使用以或等于开头而不是LIKE结尾的通配符。

不能在未编排的LIKE语句中使用索引

upper(foo) like 'bar%' -- index on upper(foo)
upper(foo) like '%bar' -- no index
reverse(upper(foo)) like 'rab%' -- index on reverse(upper(foo))
upper(foo) like '%bar%' -- no index

但是,如果您想缩小搜索窗口,您可能会发现它的用处。

检查索引是否被使用的一个简单方法是查看

SELECT * FROM pg_stat_user_indexes;

如果所有查询都与显示的查询类似,那么它们肯定不会被使用,因为模式没有被锚定。如果您想解决这个问题,您必须使用全文搜索、三角图或类似的东西来重新设计搜索。

实际上,PostgreSQL 9.1将能够使用
如“%foo%”对“contains”查询使用索引。
。看这里:@a_horse_,没有名字:Right-o。我应该添加(除非…链接到全文模块
或其他类型的字符串标记器
)。我不能使用订阅者名称):我手头只有subscriberno,这是一种“保存不同订阅类型信息的系统”,所以我有各种不同的订阅格式,其中一些格式应用于其中一些。。。