此自引用更新查询的优化/替代方案

Posted

技术标签:

【中文标题】此自引用更新查询的优化/替代方案【英文标题】:Optimize/Alternatives to this self referencing update query 【发布时间】:2012-03-07 09:42:15 【问题描述】:

我有这个更新查询:

UPDATE aggregate_usage_input t 
       JOIN (SELECT t2.id 
             FROM   aggregate_usage_input t2 
             WHERE  t2.is_excluded_total_gallons = 0 
                    AND t2.is_excluded_cohort = 0 
                    AND t2.is_excluded_outlier = 0 
             ORDER  BY t2.occupant_bucket_id, 
                       t2.residence_type_bucket_id, 
                       t2.reading_year, 
                       t2.nthreading, 
                       t2.total_gallons)t_sorted 
         ON t_sorted.id = t.id 
SET    t.rownum = @rownum := @rownum + 1 

根据排序更新 rownum 字段(实际上是按字段排序)。

select 查询需要 9 秒,因为我们使用 order by 它是可以接受的。

此查询的更新部分需要很长时间。在 400.000 条记录表上超过 5 分钟。我们需要在一分钟左右的时间内将其减少。

如何加快速度,或者你有什么替代方法来解决这个问题?

【问题讨论】:

你没有理解我的问题。 order by 是这个查询的本质,这就是我们这样做的原因。 【参考方案1】:

子查询会拖慢你的速度。在实践中,我注意到将子查询分离到临时表或表变量中更快。

试试:

CREATE TEMPORARY TABLE Temp (id int);

INSERT INTO Temp
SELECT t2.id 
FROM   aggregate_usage_input t2 
WHERE  t2.is_excluded_total_gallons = 0 
    AND t2.is_excluded_cohort = 0 
    AND t2.is_excluded_outlier = 0 
ORDER  BY t2.occupant_bucket_id, 
    t2.residence_type_bucket_id, 
    t2.reading_year, 
    t2.nthreading, 
    t2.total_gallons;

UPDATE aggregate_usage_input t
JOIN Temp t_sorted
     ON t_sorted.id = t.id 
SET t.rownum = @rownum := @rownum + 1 

【讨论】:

以上是关于此自引用更新查询的优化/替代方案的主要内容,如果未能解决你的问题,请参考以下文章

公司百万级数据查询优化方案

MySQL查询优化器工作原理解析

MySQL查询优化器工作原理解析

替代 GROUP BY 列中对相关子查询结果的引用

16周翻译

三小节内容