简体   繁体   English

优化Mysql:获取最新销售情况

[英]optimize Mysql: get latest status of the sale

In the following query, I show the latest status of the sale (by stage, in this case the number 3). 在以下查询中,我显示了销售的最新状态(按阶段,在本例中为数字3)。 The query is based on a subquery in the status history of the sale: 该查询基于销售状态历史记录中的子查询:

SELECT v.id_sale, 
IFNULL((
    SELECT (CASE WHEN IFNULL( vec.description, '' ) = ''
                    THEN ve.name
                    ELSE vec.description
                    END)
    FROM t_record veh
    INNER JOIN t_state_campaign vec ON vec.id_state_campaign = veh.id_state_campaign
    INNER JOIN t_state ve ON ve.id_state = vec.id_state
    WHERE veh.id_sale = v.id_sale
    AND vec.id_stage = 3
    ORDER BY veh.id_record DESC
    LIMIT 1
), 'x') sale_state_3
FROM t_sale v
INNER JOIN t_quarters sd ON v.id_quarters = sd.id_quarters
WHERE 1 =1
AND v.flag =1
AND v.id_quarters =4
AND EXISTS (
    SELECT '1'
    FROM t_record
    WHERE id_sale = v.id_sale
    LIMIT 1
)

the query delay 0.0057seg and show 1011 records . 查询延迟0.0057seg并显示1011条记录

Because I have to filter the sales by the name of the state as it would have to repeat the subquery in a where clause, I have decided to change the same query using joins. 因为我必须按州名来过滤销售,就像必须在where子句中重复子查询一样,所以我决定使用联接更改相同的查询。 In this case, I'm using the MAX function to obtain the latest status: 在这种情况下,我正在使用MAX函数获取最新状态:

SELECT
v.id_sale,
IFNULL(veh3.State3,'x') AS sale_state_3
FROM t_sale v
INNER JOIN t_quarters sd ON v.id_quarters = sd.id_quarters
LEFT JOIN (
    SELECT veh.id_sale, 
    (CASE WHEN IFNULL(vec.description,'') = '' 
        THEN ve.name
        ELSE vec.description END) AS State3
    FROM t_record veh
    INNER JOIN (
        SELECT id_sale, MAX(id_record) AS max_rating
                FROM(
                    SELECT veh.id_sale, id_record
                    FROM t_record veh
                    INNER JOIN t_state_campaign vec ON vec.id_state_campaign = veh.id_state_campaign AND vec.id_stage = 3
                ) m
            GROUP BY id_sale    
    ) x ON x.max_rating = veh.id_record
    INNER JOIN t_state_campaign vec ON vec.id_state_campaign = veh.id_state_campaign
    INNER JOIN t_state ve ON ve.id_state = vec.id_state
) veh3 ON veh3.id_sale = v.id_sale
WHERE v.flag = 1
AND v.id_quarters = 4

This query shows the same results (1011). 该查询显示相同的结果(1011)。 But the problem is it takes 0.0753 sec 但问题是需要0.0753秒

Reviewing the possibilities I have found the factor that makes the difference in the speed of the query: 回顾可能性,我发现了影响查询速度的因素:

AND EXISTS (
    SELECT '1'
    FROM t_record
    WHERE id_sale = v.id_sale
    LIMIT 1
)

If I remove this clause, both queries the same time delay... Why it works better? 如果删除此子句,则两个查询都将延迟相同的时间...为什么效果更好? Is there any way to use this clause in the joins? 有没有办法在联接中使用此子句? I hope your help. 希望能对您有所帮助。

EDIT 编辑

I will show the results of EXPLAIN for each query respectively: 我将分别显示每个查询的EXPLAIN结果:

q1: 1: 在此处输入图片说明

q2: q2: 在此处输入图片说明

Interesting, so that little statement basically determines if there is a match between t_record.id_sale and t_sale.id_sale. 有趣的是,因此几乎没有语句确定t_record.id_sale和t_sale.id_sale之间是否匹配。

Why is this making your query run faster? 为什么这会使查询运行得更快? Because Where statements applied prior to subSelects in the select statement, so if there is no record to go with the sale, then it doesn't bother processing the subSelect. 因为where语句在select语句中先于subSelects应用,所以如果没有与销售相关的记录,那么它就不会打扰处理subSelect。 Which is netting you some time. 这使您感到困惑。 So that's why it works better. 这就是为什么它更好地工作的原因。

Is it going to work in your join syntax? 它可以在您的联接语法中工作吗? I don't really know without having your tables to test against but you can always just apply it to the end and find out. 我真的不知道没有要测试的表,但是您始终可以将其应用到最后并找出来。 Add the keyword EXPLAIN to the beginning of your query and you will get a plan of execution which will help you optimize things. 将关键字EXPLAIN添加到查询的开头,您将获得执行计划,这将有助于您优化事物。 Probably the best way to get better results in your join syntax is to add some indexes to your tables. 在连接语法中获得更好结果的最佳方法可能是在表中添加一些索引。

But I ask you, is this even necessary? 但是我问你,这是否有必要吗? You have a query returning in <8 hundredths of a second. 您有一个查询,返回的时间不到8分之一秒。 Unless this query is getting ran thousands of times an hour, this is not really taxing your DB at all and your time is probably better spent making improvements elsewhere in your application. 除非该查询每小时要运行数千次,否则根本不会给数据库造成任何负担,并且可能会花费更多时间来改进应用程序中的其他位置。

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

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