更新MySQL查询需要很长时间才能执行 - 优化方法

时间:2017-07-07 10:11:58

标签: mysql sql

我对以下查询有疑问。

update src_woz_waardeklasse_2011 a use index(waardeklasse_main,woz_val) 
inner join waardeklasse_average b use index (waardeklasse) 
on b.waardeklasse_new = a.waardeklasse 
set a.woz_value = b.average 
where b.waardeklasse_new = a.waardeklasse; 

我正在尝试更新新列' woz_val'在' src_woz_waardeklasse_2011'使用“平均值”的表格来自' waardeklasse_average'的值表。我正在加入使用' waaderklasse'两个表中的数字。但是' src_woz_waardeklasse_2011'表是近700万条记录和' waardeklasee_average'表是46条记录。所以查询花了很长时间。 25分钟还在数。

有没有办法优化它?我确信它花了很长时间,因为我试图比较大表和小表之间的值。我已经包含了下表中的表格结构。

src_woz_waardeklasse_2011
+----------------------+---------------------------+------+-----+---------+-
---------------+
| Field                | Type                      | Null | Key | Default | 
Extra          |
+----------------------+---------------------------+------+-----+---------+-
---------------+
| id                   | int(11) unsigned          | NO   | PRI | NULL    | 
auto_increment |
| postcode             | varchar(150)              | YES  | MUL | NULL    |                
|
| huisnummeraanduiding | varchar(150)              | YES  |     | NULL    |                
|
| huisletter           | varchar(150)              | YES  |     | NULL    |                
|
 soort_woonobject     | varchar(150)              | YES  |     | NULL    |                
|
| bouwjaar             | varchar(150)              | YES  |     | NULL    |                
|
| bouwjaarsklasse      | varchar(150)              | YES  |     | NULL    |                
|
| inhoud               | varchar(150)              | YES  |     | NULL    |                
|
| reg_oppervlak        | varchar(150)              | YES  |     | NULL    |                
|
| woz_value            | int(15) unsigned zerofill | YES  | UNI | NULL    |                
|
| reg_oppervlak_bn     | varchar(150)              | YES  |     | NULL    |                
|
| waardeklasse         | int(10)                   | NO   | PRI | NULL    |                
|
| waardepeildatum      | varchar(150)              | YES  |     | NULL    |                
|
| zipandnumber         | varchar(150)              | YES  |     | NULL    |                
|
+----------------------+---------------------------+------+-----+---------+-
---------------+

waardeklasse_average
+-------------------------+---------+------+-----+---------+-------+
| Field                   | Type    | Null | Key | Default | Extra |
+-------------------------+---------+------+-----+---------+-------+
| waardeklasse_average_id | int(11) | NO   |     | NULL    |       |
| waardeklasse_new        | int(10) | NO   | PRI | NULL    |       |
| lower                   | int(11) | NO   |     | NULL    |       |
| higher                  | int(11) | NO   |     | NULL    |       |
| average                 | int(11) | NO   | PRI | NULL    |       |
+-------------------------+---------+------+-----+---------+-------+ 

3 个答案:

答案 0 :(得分:0)

update src_woz_waardeklasse_2011 a use index(waardeklasse_main,woz_val) 
inner join waardeklasse_average b use index (waardeklasse) 
on b.waardeklasse_new = a.waardeklasse 
set a.woz_value = b.average 

不需要条件的地方。 正如您已在 On 子句中提到该条件。

尝试以上查询。

希望这会对你有所帮助。

答案 1 :(得分:0)

首先,您不需要where条款。其次,删除索引提示:

update src_woz_waardeklasse_2011 ww inner join
       waardeklasse_average wa 
       on wa.waardeklasse_new = ww.waardeklasse 
    set ww.woz_value = wb.average ;

然后,尝试src_woz_waardeklasse_2011(waardeklasse)上的索引。这应该会改善执行计划。

您还可以检查第二个表中的46个记录是否实际上对应于46个更新。如果连接条件错误,您可以更新所有记录。

编辑:

索引与您的问题无关。更新700万条记录需要很长时间。您可以考虑在临时表中创建所需的数据,然后截断原始表并将新行插入其中。否则,一次批量更新几行。

答案 2 :(得分:0)

update src_woz_waardeklasse_2011 a use index(waardeklasse_main,woz_val) 
Left join waardeklasse_average b 
on b.waardeklasse_new = a.waardeklasse 
set a.woz_value = b.average 
where b.waardeklasse_new = a.waardeklasse;

使用上述查询 - 您可以使用左连接和where条件来加速查询。

另外,不要使用具有46条记录的第二个表的索引,这会影响性能 - 如果表记录较少,则索引会产生更多负担,在这种情况下,没有索引的全表扫描要好很多。此外,如果第一个表中有一个集群索引(700万),请删除它们并运行查询,因为对于每个更新,您执行默认表结构并且页面对齐将在聚簇索引中更新。希望这会有所帮助..!