优化Mysql:获取销售的最新状态

时间:2012-10-17 17:45:04

标签: mysql optimization subquery exists

在以下查询中,我显示了销售的最新状态(按阶段,在本例中为数字3)。该查询基于销售状态历史记录中的子查询:

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
)

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

编辑

我将分别为每个查询显示EXPLAIN的结果:

Q1: enter image description here

Q2: enter image description here

1 个答案:

答案 0 :(得分:0)

有趣,因此小语句基本上确定t_record.id_sale和t_sale.id_sale之间是否匹配。

为什么这会让您的查询运行得更快?因为Where语句在select语句中的subSelects之前应用,所以如果没有记录与销售一起使用,那么它就不会处理subSelect。这对你有所帮助。所以这就是它更好的原因。

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

但我问你,这是否有必要?您有一个以<8百分之一秒为单位返回的查询。除非这个查询每小时运行数千次,否则这根本不会对您的数据库造成负担,并且您的时间可能更适合在应用程序的其他地方进行改进。