【问题标题】:SQL - which index will speed up the COUNT() querySQL - 哪个索引将加快 COUNT() 查询
【发布时间】:2021-01-31 15:50:02
【问题描述】:

我有一个非常简单的 Postgres 数据库,看起来像这样(它在 Django 中定义,但这无关紧要):

class Country:
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    # Not important
    # name = models.TextField(nullable=False)

class City:
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    # name = models.TextField(nullable=False)
    country = models.ForeignKey(Country)

class Street:
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    # name = models.TextField(nullable=False)
    city = models.ForeignKey(City)
    # Just some boolean field
    is_big = models.BooleanField(nullable=False)

我想查询一个国家“大”街道的数量。这样做是这样的:

SELECT COUNT(*)
  FROM Street
 INNER JOIN City
    ON Street.city_id = City.id
 WHERE Street.is_big = true AND City.country_id = 'xxxxxxx'::uuid

数据库中总共有约 20 个国家、约 5000 个城市和约 200 万条街道,虽然不多,但此查询有时可能需要 1-2 秒。

我应该添加什么索引来加快这个查询?

【问题讨论】:

  • 索引WHERE子句中的外键和所有字段。
  • 像往常一样,您需要分析查询的EXPLAIN ANALYZE 输出,以找出在您的特定情况下减慢它的原因。来自Understanding EXPLAIN“20 索引在这里有帮助吗?”的示例,其中带有 WHERE 子句的查询“需要读取 99.95% 的表。在这种情况下它永远不会使用索引 "

标签: python sql django postgresql indexing


【解决方案1】:

这是您的查询:

SELECT COUNT(*)
FROM Street s JOIN
     City c
     ON s.city_id = c.id
WHERE s.is_big = true AND c.country_id = 'xxxxxxx'::uuid;

对此有两种可能的方法。但是,我怀疑两者都不会在所有情况下都能很好地工作——我猜有些国家有很多大街道。

第一种方法是在大街上过滤:street(is_big, city_id)city(id, country_id)。第二种是针对特定国家进行过滤:city(country_id, id)street(city_id, is_big)

如果数据库是静态的,那么查询可以使用仅索引扫描——假设数据是“可见的”。

【讨论】:

  • 我什至不确定它是什么意思
  • @user972014 。 . .它为您提供了两组索引供您尝试。
猜你喜欢
  • 2013-06-25
  • 1970-01-01
  • 2011-05-25
  • 1970-01-01
  • 2013-05-31
  • 2014-12-31
  • 2013-08-28
  • 2015-04-23
  • 2011-01-04
相关资源
最近更新 更多