2012-10-17 39 views
0

在下面的查询中,我显示销售的最新状态(按阶段,在这种情况下为数字3)。查询是基于在售的状态历史记录的子查询:优化Mysql:获取销售的最新状态

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 
) 

查询延迟0.0057seg并显示1011记录

因为我必须按照状态名称过滤销售情况,因为它必须在where子句中重复子查询,所以我决定使用连接更改相同的查询。在这种情况下,我使用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 

此查询显示相同的结果(1011)。但问题是它需要0.0753秒

审查的可能性我发现,使得查询的速度差异的因素:

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

如果我删除此条款,两个询问相同时间延迟...为什么它更好?有什么方法可以在连接中使用这个子句?我希望你的帮助。

编辑

我会告诉解释每个分别查询的结果:

Q1: enter image description here

Q2: enter image description here

回答

0

利息ing,这样基本上判断t_record.id_sale和t_sale.id_sale是否匹配。

这是什么让你的查询运行速度更快?由于where语句在select语句中的subSelects之前应用,所以如果没有记录与销售一起使用,那么它不会打扰处理subSelect。这是你的一些时间。所以这就是为什么它效果更好。

它会在你的连接语法中工作吗?我真的不知道没有你的桌子来测试,但你总是可以把它应用到最后并找出答案。将关键字EXPLAIN添加到查询的开头,您将得到一个执行计划,它可以帮助您优化内容。在您的连接语法中获得更好结果的最好方法可能是向表中添加一些索引。

但我问你,这是否有必要?你有一个查询返回在<百分之八十秒。除非这个查询每小时运行几千次,否则这根本不是真正对您的数据库征税,您的时间可能会更好地用于在应用程序的其他地方进行改进。

+0

感谢您的回复。对于我来说,这是一个重要的时刻,原因很简单,我所显示的查询只是销售状态。他真正的查询显示每个阶段的不同状态(每个子查询/联接),如果我们添加时间,则有一段时间查询可能需要1.5秒。对0.3xxx秒。所以知道是否有任何方法来优化连接会很有趣。索引表例如在Table t_record中:i_id_record,i_id_state_campaign,i_id_sale ... – csotelo