简体   繁体   English

Postgres 查询需要很长时间才能获得结果

[英]Postgres query taking long time to get results

I have a problem with my postgres query.我的 postgres 查询有问题。 The query taking too long, almost 27 seconds to get the results and i don't know what i need to do to solve查询花费的时间太长,将近 27 秒才能得到结果,我不知道我需要做什么来解决

SELECT 
    sales.*, 
    customers.name AS customer_name, 
    customers.cpf_pf AS cpf, 
    customers.cnpj_pj AS cnpj, 
    customers.juridica AS tipo_pessoa, 
    status_sales.name AS status_name, 
    sales_status_histories.created_at AS data_modificacao, 
    sales_status_histories.obs as observacao, 
    users.name AS nome_vendedor

FROM sales 

RIGHT JOIN customers ON sales.customer_id = customers.id
RIGHT JOIN sales_user_owners ON sales_user_owners.sale_id = sales.id
RIGHT JOIN sales_status_histories ON sales_status_histories.sale_id = sales.id
RIGHT JOIN status_sales ON status_sales.id = sales_status_histories.status_sale_id
RIGHT JOIN users ON users.id = sales_user_owners.user_id 

WHERE sales_status_histories.id IN (SELECT id FROM ( SELECT *, row_number() over (PARTITION BY sale_id ORDER BY created_at DESC) AS rn FROM sales_status_histories) AS ssh WHERE rn=1 AND Date( (sales_status_histories.created_at at time zone 'UTC') at time zone 'America/Sao_Paulo') BETWEEN '2018-01-01 00:00:00' AND '2018-01-04 23:59:59')
    AND sales_user_owners.id IN ( SELECT id FROM ( SELECT *, row_number() over (PARTITION BY sale_id ORDER BY created_at DESC) AS rn FROM sales_user_owners) AS so WHERE rn=1)

The big problem is here:最大的问题在这里:

WHERE sales_status_histories.id IN (SELECT id FROM ( SELECT *, row_number() over (PARTITION BY sale_id ORDER BY created_at DESC) AS rn FROM sales_status_histories) AS ssh WHERE rn=1 AND Date( (sales_status_histories.created_at at time zone 'UTC') at time zone 'America/Sao_Paulo') BETWEEN '2018-01-01 00:00:00' AND '2018-01-04 23:59:59')

This part searches the last status of the sale in the sales_status_histories table with specific range of time这部分在 sales_status_history 表中搜索特定时间范围内的上次销售状态

The sale can has multiples statuses in different phases, but only the last is the current status and just the last is important to me in this query, because i need get all sales that were updated in specific range of time销售在不同阶段可以有多个状态,但只有最后一个是当前状态,在此查询中只有最后一个对我很重要,因为我需要获取在特定时间范围内更新的所有销售

Someone can help me to build a optimized query that take less time to get the same results, please?有人可以帮我构建一个优化的查询,花费更少的时间来获得相同的结果,好吗?

See the entire structure of my database in this image:在这张图片中查看我的数据库的整个结构: 形象

My application is a ruby on rails with postgres我的应用程序是带有 postgres 的 ruby​​ on rails

INDEXES:指数: 在此处输入图片说明

--- EDIT 1 ---- --- 编辑 1 ----

Sometimes i need to find the sales with specific current status.有时我需要找到具有特定当前状态的销售。 Using the @bma suggestion i tried something like this:使用@bma 建议我尝试了这样的事情:

(SELECT id, row_number() OVER (PARTITION BY sale_id ORDER BY created_at DESC) AS rn FROM sales_status_histories WHERE status_sale_id IN (2) AND DATE((sales_status_histories.created_at AT TIME ZONE 'UTC') AT TIME ZONE 'America/Sao_Paulo') BETWEEN '2018-01-01' AND '2018-01-04') AS ssh WHERE rn=1

As you can see, I added the status_sale_id IN (2), but in this case only sales that at some point (not always the current status) had that specific status are returned如您所见,我添加了 status_sale_id IN (2),但在这种情况下,仅返回在某些时候(并非总是当前状态)具有特定状态的销售

Not a full answer, but a thing to try might be making the query more readable with a WITH clause to pull out the sales_status_histories rows you are interested in first, and then join the main SELECT on that.不是一个完整的答案,但可以尝试使用 WITH 子句使查询更具可读性,以首先提取您感兴趣的 sales_status_history 行,然后加入主要的 SELECT。

Note: you can maybe use SELECT DISTINCT sale_id FROM sales_status_histories ORDER BY created_at DESC to get only the row with the latest change instead of a subquery with row_number().注意:您可以使用 SELECT DISTINCT sale_id FROM sales_status_histories ORDER BY created_at DESC 来仅获取具有最新更改的行,而不是使用 row_number() 的子查询。 I don't know if that's more efficient, but it's simpler to read.我不知道这是否更有效,但阅读起来更简单。

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

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