如何提高MySQL查询的性能?

时间:2015-09-17 05:56:18

标签: mysql database performance

在chipChange表中,我有数百万条记录。我想要学习的是优化下面的查询的方法。目前它看起来需要花费数小时才能

  1. 从chipChange表中获取数据
  2. 更新playerStats表
  3. 您认为我如何提高此类查询的效果?

    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;
    

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

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

使用单独的子查询(取决于你的chipChange表所具有的索引)可能是值得的,每个查询可以使用索引来获取计数,然后只需将这些单独的查询LEFT OUTER加入到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);