简体   繁体   中英

How to improve performance of that MySQL query?

In chipChange table, I have millions of records. What I want to learn is the way to optimize the query below. Currently it looks it is going to take hours and hours to

  1. fetch the data from chipChange table
  2. update playerStats table

How do you think I can improve the performance of this type of query?

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;

This query can create locking in your db and even can choke the db server.

better option will be a stored procedure in which first fetch all values computed values in select query and keep them in cursor then update your target table one by one row by cursor.

I don't think that query is going to use indexes usefully at all.

It might be worth using a separate sub query (depending in the indexes your chipChange table has), which can each use indexes to get the counts, and then just LEFT OUTER JOIN those individual queries to playerStats.

Something like this:-

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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