-1

我有两个表:token_type,CUST_ID(小学) 2. 200K数据 列pm_tmp表: 有大约1000万的数据 列1.用户表ID(主|自动增加),user_id说明Mysql性能:哪个查询需要更多时间?

USER_ID是CUST_ID外键

1接近角/查询:

update user set token_type='PRIME' 
where cust_id in (select user_id from pm_tmp where id between 1 AND 60000); 

第二接近角/查询:在这里我们将运行下面的查询针对不同的cust_id单独为60000个记录:

update user set token_type='PRIME' where cust_id='1111110'; 
+3

当你测量它时,你得到了什么结果? –

+0

第二种方法花费的时间更少。但我试图找出原因。 –

+0

这是因为,第一个查询将需要为您的innodb缓冲池配置足够的内存以使其快速执行。第二个是单事务查询将需要相对较少的时间。 – Nans

回答

0

对于第一个查询,理论上时间会少一些,因为它涉及的提交数量较少,而索引重建次数较少。但是,我会建议采用第二种方法,因为它的控制更好,并且时间会更少,您可以事先考虑执行2个单独的套件。

注意:第一个查询将需要足够的内存供应给mysql缓冲区以快速执行。第二个查询是独立的单个事务查询的集合,它们将需要相对较少的内存,因此如果在有限的内存环境中执行,则会显得更快。

那么,你也可以用这种方式重写第一个查询。

update user u, pm_tmp p set u.token_type='PRIME' where u.cust_id=p.id and p.in <60000;

0

MySQL的一些版本的麻烦优化in。我建议:

update user u join 
     pm_tmp pt 
     on u.cust_id = pt.user_id and pt.id between 1 AND 60000 
    set u.token_type = 'PRIME' ; 

(注:这假定cust_idpm_temp重复。如果这是可能的,你会希望有一个select distinct子查询。)

你的第二个版本通常会相当慢,因为它需要执行数千个查询而不是一个查询。一个考虑可能是update。随着更新数量的增加,日志记录和锁定可能会变得更加复杂。我实际上对MySQL内部知道的知之甚少,不知道这是否会对性能产生重大影响。

0

IN (SELECT ...)很差优化。 (我无法提供具体细节,因为UPDATEIN在某些最新版本的MySQL中已经得到了更好的优化。)只要说“避免IN (SELECT ...)”即可。

你的第一句话应该说“行”而不是“列”。

回到问题的其余部分。 60K太大了。我建议只有1000.除此之外,戈登的答案可能是最好的。

但是...您没有使用OFFSET;做不是被诱惑使用它;当你越走越远时,它会导致性能下降。

另一件事。每块后面有COMMIT。否则你建立一个巨大的撤销日志;这增加了成本。 (这也是1K可能比60K更快的原因。)

但是等一下!你为什么要更新一个巨大的桌子?那就是通常是这是坏模式设计的标志。请解释数据流。

也许你计算了哪些项目标记为'素数'?那么,你可以保留这个清单,并在SELECTs中做JOINs以发现阅读时的主要性。这完全消除了UPDATE的问题。当然,JOIN的成本,但不是很多。