【问题标题】:Django-Postgres WHERE query using varchar_pattern_ops index instead of pkey index使用 varchar_pattern_ops 索引而不是 pkey 索引的 Django-Postgres WHERE 查询
【发布时间】:2019-09-12 08:24:56
【问题描述】:

我在这张表上有一个 Django-Postgres 设置 -

class User(models.Model):
    id = models.CharField(max_length=255, primary_key=True)

运行迁移会在字段上创建两个索引(这是 Django 自动执行的操作,正如我在运行 sqlmigrate 时检查的那样) - 一个用于 pkey,一个用于varchar_pattern_ops -

\d+ "user";

Column|            Type          | Modifiers | Storage  | Stats target | Description 
------+--------------------------+-----------+----------+--------------+-------------
 id   |  character varying(255)  | not null  | extended |              | 

Indexes:
"user_pkey" PRIMARY KEY, btree (id)
"user_id_90845346_like" btree (id varchar_pattern_ops)

据我了解,如果我运行此查询

select * from "user" where id='id1234';

它应该使用user_pkey。相反,它使用user_id_90845346_like

explain analyze select * from "user" where id='id1234';

 Index Scan using "user_id_90845346_like" on "user"  (cost=0.41..8.43 rows=1 width=770) (actual time=0.033..0.0
33 rows=0 loops=1)
   Index Cond: ((id)::text = 'id1234'::text)
 Planning time: 1.335 ms
 Execution time: 0.072 ms
(4 rows)

我也没有看到任何强制 Postgres 使用索引的选项,但我真正想知道的是为什么 = 搜索不使用主键。 like text% 搜索不应该使用varchar_pattern_ops 索引吗?

【问题讨论】:

    标签: django postgresql postgresql-9.5 database-indexes django-1.9


    【解决方案1】:

    postgres 驱动程序总是会选择varchar_pattern_ops 索引,如果它存在于您要索引的列是 varchar 列或其某种变体的情况下。简单来说,因为您要索引的列包含字符串,所以驱动程序将选择最适合字符串的索引(当它可用时)。如果您将主键存储为整数,驱动程序将使用btree 索引。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-26
      • 2017-09-07
      • 2017-09-12
      • 2023-03-29
      • 1970-01-01
      • 2016-10-13
      • 2020-09-01
      相关资源
      最近更新 更多