Django 过滤器未使用 Postgresql JSONField 上的索引
Django filter is not using the index on Postgresql JSONField
我有一个包含 PostgreSQL jsonb field
:
的 Django 模型
class SocialUser(models.Model):
id = models.BigIntegerField(primary_key=True)
data = JSONField(blank=True, null=True, db_index=True)
数据字段包含一个 username
属性。
我已经通过
索引了这个属性
CREATE INDEX ON users_socialuser ((data->>'username'));
当我通过 Django ORM 使用 id 查询时,
SocialUser.objects.get(id=123)
并通过 pgAdmin
SELECT * FROM users_socialuser WHERE id = 123
他们都很快。
但是当我使用 JSONField 的属性用户名进行查询时,pgAdmin SQL 查询
SELECT * FROM users_socialuser WHERE data->>'username' = 'abc'
仍然同样快,而
SocialUser.objects.get(data__username='abc')
非常慢。
Django ORM 似乎没有使用 username
属性上的索引。
为什么会这样?我可以在 Django ORM 中明确强制索引吗?有解决办法吗?
探索 Django ORM 生成的查询,我注意到 WHERE 子句就像
data -> 'screen_name' = 'abc'
注意单箭头 ->
而不是 ->>
。
所以,我用单箭头建立了索引
CREATE INDEX ON users_socialuser ((data->'username'));
并且 ORM 查询现在也很快了。
我有一个包含 PostgreSQL jsonb field
:
class SocialUser(models.Model):
id = models.BigIntegerField(primary_key=True)
data = JSONField(blank=True, null=True, db_index=True)
数据字段包含一个 username
属性。
我已经通过
索引了这个属性CREATE INDEX ON users_socialuser ((data->>'username'));
当我通过 Django ORM 使用 id 查询时,
SocialUser.objects.get(id=123)
并通过 pgAdmin
SELECT * FROM users_socialuser WHERE id = 123
他们都很快。
但是当我使用 JSONField 的属性用户名进行查询时,pgAdmin SQL 查询
SELECT * FROM users_socialuser WHERE data->>'username' = 'abc'
仍然同样快,而
SocialUser.objects.get(data__username='abc')
非常慢。
Django ORM 似乎没有使用 username
属性上的索引。
为什么会这样?我可以在 Django ORM 中明确强制索引吗?有解决办法吗?
探索 Django ORM 生成的查询,我注意到 WHERE 子句就像
data -> 'screen_name' = 'abc'
注意单箭头 ->
而不是 ->>
。
所以,我用单箭头建立了索引
CREATE INDEX ON users_socialuser ((data->'username'));
并且 ORM 查询现在也很快了。