连接两个表时如何优化查询?

问题描述 投票:0回答:1

我的系统使用 PostgreSQL 作为数据库。我在使用查询将两个大表连接在一起时遇到问题。我将简要描述这些表格如下:

Location:
 - id: uuid
 - name: string (indexes)
 - country: string (indexes)
 - number: string

Product:
 - id: uuid
 - name: string
 - score: number (indexes)
 - rate: number (indexes)
 - report: number (indexes)
 - lock: boolean (indexes)
 - location_id: uuid (not null) (indexes)


Location and Product will be 1-1 relation unique. Location can be has product or not.

我使用了以下查询:

select l.id, l.name, l.number, p.id as pId, p.name, p.score, p.rate
from location l
left join product p on p.location_id = l.id
where l.country = 'US'
and l.id < 'xxx-yyy-zzz'
and (p.name is not null or l.name is not null)
and p.score > 1 and p.rate > 4 and p.lock = false
order by id desc
limit 100

请注意,产品表和位置表都有大量记录。每个表大约包含数百万到数千万条记录。如何加快查询执行速度?对于某些国家/地区,它运行得非常快,但对于其他国家/地区,尽管记录较少,但运行速度很慢。

sql postgresql postgresql-performance
1个回答
0
投票

您可以尝试创建索引:

  1. 在位置(国家/地区,id)上创建索引,以帮助按 l.country 和 l.id 进行过滤。
  2. 在产品(location_id、score、rate、lock)上创建索引,以协助 p 上的连接和过滤。
CREATE INDEX idx_location_country_id ON location(country, id);
CREATE INDEX idx_product_location_score_rate_lock ON product(location_id, score, rate, lock);

注:

p.lock 上的过滤:在某些情况下,如果该列上没有索引,p.lock = false 可能是一个昂贵的条件。您可能需要确保 p.lock 已建立索引。

避免过多的 NULL 检查:由于 p.name IS NOT NULL 和 l.name IS NOT NULL 是可能代价高昂的条件,因此请确保对经常查询 NULL 检查的列建立索引。

Limit 子句放置:正确放置 LIMIT 100 以限制排序操作后的结果。

此外,您还可以根据您的使用情况尝试表分区

© www.soinside.com 2019 - 2024. All rights reserved.