Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何提高MySQL查询的性能?_Mysql_Database_Performance - Fatal编程技术网

如何提高MySQL查询的性能?

如何提高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

在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 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…
    ,以便我们可以验证它是否以预期的方式执行查询。应首先查看计划:}虽然锁可以阻止其他查询,但它们不会减慢当前查询的速度。游标可能更慢。因为游标将基于主键更新目标表,因此,不要太慢。如果你认为有什么不同,请解释一下,以便深入了解这个问题。