【问题标题】:How to improve performance of that MySQL query?如何提高 MySQL 查询的性能?
【发布时间】:2015-09-17 05:56:17
【问题描述】:

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

【问题讨论】:

  • 请为两张表提供SHOW CREATE TABLE
  • 你为什么需要那个? @RickJames 注意:uid 列在两个表中都有索引。
  • 这是一些有用的信息。然后是使用的引擎。以及行是否加载了统计信息以外的内容。也许数据类型会激发一些需要提出的观点。
  • 另外,如果您运行的是 5.6,请提供EXPLAIN UPDATE ...,以便我们验证它是否以预期的方式执行查询。

标签: mysql database performance


【解决方案1】:

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

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

【讨论】:

  • 应该首先查看计划:} 虽然锁可以阻止其他查询,但它们不会减慢当前查询。
  • 光标可能会更慢。
  • 因为游标会根据主键更新目标表,所以应该不会很慢..如果您认为不同,请您解释一下以深入了解该问题。
【解决方案2】:

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

可能值得使用单独的子查询(取决于您的 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);

【讨论】:

    猜你喜欢
    • 2013-03-21
    • 2013-03-28
    • 1970-01-01
    • 2011-12-03
    • 2023-04-08
    • 2023-03-14
    • 1970-01-01
    • 2014-11-09
    • 2015-06-06
    相关资源
    最近更新 更多