如何提高MySQL查询的性能?
在chipChange表中,我有数百万条记录。我想学习的是优化以下查询的方法。目前看来要花上好几个小时才能完成如何提高MySQL查询的性能?,mysql,database,performance,Mysql,Database,Performance,在chipChange表中,我有数百万条记录。我想学习的是优化以下查询的方法。目前看来要花上好几个小时才能完成 从chipChange表中获取数据 更新playerStats表 您认为我可以如何提高这类查询的性能 UPDATE playerStats pst INNER JOIN ( Select chipChange.uid, sum(case when (type=2) and (eventId!=16 and eventId!=17 and eventId!=18 and eventI
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;
这个查询会在数据库中创建锁定,甚至会阻塞数据库服务器
更好的选择是一个存储过程,在该过程中,首先获取select查询中的所有值和计算值,并将它们保留在游标中,然后逐行逐行更新目标表。我认为查询根本不会使用索引 可能值得使用一个单独的子查询(取决于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);
请为这两个表提供
SHOW CREATE TABLE
。为什么需要@RickJames注意:uid列在两个表中都被索引。这是一点有用的信息。然后是使用的发动机。以及行是否加载了除统计数据以外的其他内容。也许这些数据类型会激发一些观点。另外,如果您运行的是5.6,请提供EXPLAIN UPDATE…
,以便我们可以验证它是否以预期的方式执行查询。应首先查看计划:}虽然锁可以阻止其他查询,但它们不会减慢当前查询的速度。游标可能更慢。因为游标将基于主键更新目标表,因此,不要太慢。如果你认为有什么不同,请解释一下,以便深入了解这个问题。