使用重复记录优化表上的mysql更新语句

时间:2017-11-16 02:24:40

标签: mysql join duplicates query-optimization updates

我在同一架构中有两张表,即付款和付款方式。 tt_emails如下所示:

payments表:包含大约2700万条付款记录,其中包含重复的customer_id,用于支付付款的数月。

+--------------+------------------+------+-----+---------+----------------+
| Field        | Type             | Null | Key | Default | Extra          |
+--------------+------------------+------+-----+---------+----------------+
| id           | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| report_cust  | varchar(100)     | YES  |     | NULL    |                |
| payment_type | varchar(100)     | YES  |     | NULL    |                |
| month        | varchar(1000)    | YES  |     | NULL    |                |
| year         | varchar(1000)    | YES  |     | NULL    |                |
| amount       | varchar(1000)    | YES  |     | NULL    |                |
| pmnt_date    | varchar(1000)    | YES  |     | NULL    |                |
| mapping      | varchar(100)     | YES  |     | NULL    |                |
+--------------+------------------+------+-----+---------+----------------+

tt_emails表:包含~916k记录。

+-------------+------------------+------+-----+---------+----------------+
| Field       | Type             | Null | Key | Default | Extra          |
+-------------+------------------+------+-----+---------+----------------+
| id          | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| cnc_id      | varchar(100)     | YES  |     | NULL    |                |
| customer_id | varchar(100)     | YES  |     | NULL    |                |
| email       | varchar(1000)    | YES  |     | NULL    |                |
| email_type  | varchar(1000)    | YES  |     | NULL    |                |
+-------------+------------------+------+-----+---------+----------------+

要尝试实现的目标是,使用tt_emails表中mapping中的值更新付款表中的email_type列。我使用下面的更新语句,我已经测试过,并且似乎在~6秒内更新了10条记录(id <= 10)。

Update payments p 
  join tt_emails tmp
    on p.report_cust=tmp.customer_id
  set p.mapping = tmp.email_type
  where p.report_cust is not null;

我已将更新查询运行了近12个小时,但它似乎仍在运行,我怀疑这可能是由于report_cust不唯一并重复自身的更新语句中的连接条件鉴于其付款历史。

有没有更好的方法来处理这个并让更新运行得更快?我最初尝试了一个子查询,但我读到它比连接慢。

1 个答案:

答案 0 :(得分:0)

没有索引! (PK除外)

on p.report_cust=tmp.customer_id

需要

p:  INDEX(report_cust)
tmp:  INDEX(customer_id)

where p.report_cust is not null

可能会受益于

INDEX(report_cust)

更好的是这个&#34;覆盖&#34; (和&#34;复合&#34;)索引:

tmp:  INDEX(customer_id, email_type)

使用数据类型实现。如果year真的是&#34;年&#34;,拼出它需要1000个字符吗? 4会这样做。 INT会更好。更好的是数据类型YEAR

对&#34;类型&#34;。

考虑ENUM

ids(VARCHARcnc_id)需要customer_id,这种情况很少见(但并非不可能)。

没有索引,它必须扫描整个表。考虑查看未以任何方式排序的916K名称列表。此外,做了2700万次!