繁体   English   中英

如何提高该 MySQL 查询的性能?

[英]How to improve performance of that MySQL query?

在chipChange表中,我有数百万条记录。 我想学习的是优化下面查询的方法。 目前看起来这将需要几个小时和几个小时

  1. 从chipChange表中获取数据
  2. 更新 playerStats 表

您认为我可以如何提高此类查询的性能?

UPDATE playerStats pst
INNER JOIN
(
Select 
chipChange.uid, 
sum(case when (type=2) and (eventId!=16 and eventId!=17 and eventId!=18 and eventId!=10) then 1 else 0 end) sum1,
sum(case when (type=1 or type=3 or type=9) and (eventId!=16 and eventId!=17 and eventId!=18 and eventId!=10) then 1 else 0 end) sum2,
sum(case when type=2 and eventId=10 then 1 else 0 end) sum3,
sum(case when (type=1 or type=3 or type=9) and eventId=10 then 1 else 0 end) sum4,
sum(case when type=2 and (eventId=16 or eventId=17 or eventId=18) then 1 else 0 end) sum5,
sum(case when (type=1 or type=3 or type=9) and (eventId=16 or eventId=17 or eventId=18) then 1 else 0 end) sum5
from chipChange
where (type=1 or type=2 or type=3 or type=9)
group by uid
) cht on pst.uid=cht.uid
SET 
pst.total1 = cht.sum1 + cht.sum2,
pst.total2 = cht.sum1,    
pst.total3 = cht.sum3 + cht.sum4,
pst.total4 = cht.sum3,
pst.total5 = cht.sum5 + cht.6,
pst.total6 = cht.sum5;

此查询可以在您的数据库中创建锁定,甚至可以阻塞数据库服务器。

更好的选择将是一个存储过程,其中首先获取选择查询中的所有计算值并将它们保留在游标中,然后通过游标一行一行地更新目标表。

我认为该查询根本不会有用地使用索引。

可能值得使用单独的子查询(取决于您的chipChange 表具有的索引),每个子查询都可以使用索引来获取计数,然后将这些单独的查询左外连接到 playerStats。

像这样的东西:-

UPDATE playerStats pst
LEFT OUTER JOIN
(
    SELECT uid, COUNT(*) AS sum1 FROM chipChange WHERE type=2 and eventId NOT IN (16, 17, 18, 10) GROUP BY uid
) sub1 ON sub1.uid = pst.uid
LEFT OUTER JOIN
(
    SELECT uid, COUNT(*) AS sum2 FROM chipChange WHERE type IN (1, 3, 9) and eventId NOT IN (16, 17, 18, 10) GROUP BY uid
) sub2 ON sub2.uid = pst.uid
LEFT OUTER JOIN
(
    SELECT uid, COUNT(*) AS sum3 FROM chipChange WHERE type = 2 and eventId = 10 GROUP BY uid
) sub3 ON sub3.uid = pst.uid
LEFT OUTER JOIN
(
    SELECT uid, COUNT(*) AS sum4 FROM chipChange WHERE type IN (1, 3, 9) and eventId = 10 GROUP BY uid
) sub4 ON sub4.uid = pst.uid
LEFT OUTER JOIN
(
    SELECT uid, COUNT(*) AS sum5 FROM chipChange WHERE type = 2 and eventId IN (16, 17, 18) GROUP BY uid
) sub5 ON sub5.uid = pst.uid
LEFT OUTER JOIN
(
    SELECT uid, COUNT(*) AS sum6 FROM chipChange WHERE type IN (1, 3, 9) and eventId IN (16, 17, 18) GROUP BY uid
) sub6 ON sub6.uid = pst.uid
SET 
pst.total1 = COALESCE(sub1.sum1, 0) + COALESCE(sub2.sum2, 0),
pst.total2 = COALESCE(sub1.sum1, 0),    
pst.total3 = COALESCE(sub3.sum3, 0) + COALESCE(cht.sum4, 0),
pst.total4 = COALESCE(sub3.sum3, 0),
pst.total5 = COALESCE(sub5.sum5, 0) + COALESCE(sub6.sum6, 0),
pst.total6 = COALESCE(sub5.sum5, 0);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM