简体   繁体   English

SQL - 哪个索引将加速 COUNT() 查询

[英]SQL - which index will speed up the COUNT() query

I have a very simple Postgres database that looks like that (it's defined in Django but this doesn't matter):我有一个非常简单的 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)

I want to query the number of "big" streets in a country.我想查询一个国家的“大”街道数量。 This is done like that:这是这样做的:

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

There are a total of around ~20 countries, ~5000 cities and ~2 million streets in the database, which is not a lot, yet this query can take sometimes 1-2 seconds.数据库中总共有大约 20 个国家、大约 5000 个城市和大约 200 万条街道,数量并不多,但这个查询有时可能需要 1-2 秒。

What index should I add to make this query fast?我应该添加什么索引来使这个查询更快?

This is your query:这是您的查询:

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;

There are two possible approaches for this.为此,有两种可能的方法。 However, I suspect that neither will work really well in all cases -- I am guessing that some countries have lots of big streets.然而,我怀疑这两种方法在所有情况下都不会很好——我猜有些国家有很多大街道。

The first approach is to filter on the big streets: street(is_big, city_id) and city(id, country_id) .第一种方法是过滤大街道: street(is_big, city_id)city(id, country_id) The second is to filter on the specific country: city(country_id, id) and street(city_id, is_big) .第二个是过滤特定国家: city(country_id, id)street(city_id, is_big)

If the database is static, then the query can use an index-only scan -- assuming the data is "visible".如果数据库是静态的,那么查询可以使用仅索引扫描——假设数据是“可见的”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM