【问题标题】:MySQL replacement for sum(if(xxx,1,0))MySQL 替换 sum(if(xxx,1,0))
【发布时间】:2013-08-01 09:13:19
【问题描述】:

您好,我需要一些帮助来优化此代码,目前运行 SQL 查询需要 38 秒,将其加载为视图需要 23 秒。 这是背景—— 当成员使用链接时重定向表记录并记录他们去哪里、何时返回以及处于何种状态。 项目表管理我需要的每个项目信息。 目前,我确实有第三个表,它保存每个项目的计数,每次将记录添加到重定向表时都会更新该计数,但是计数可能有点不可靠。服务器每小时运行一次查询以修复/验证计数。

有没有什么好方法可以不用 sum(if(xxx,1,0)) 来计算列数?

Select projects.ID as ID,cid,name as name,state as status,
                sum(if(status="complete",1,0)) as complete,cpc,
                cpc*ss as mmkingaku,
                cpc*sum(if(status="complete",1,0)) as total,
                sum(if(status="screenout",1,0)) as screenout,
                sum(if(status="quotafull",1,0)) as quotafull, 
                sum(if(status="short",1,0)) as short,
                sum(if(status="gate",1,0)) as gate,
                sum(if(status is null,1,0)) as empty,
                sum(if(status="complete",1,0))/(sum(if(status="complete",1,0))+sum(if(status="screenout",1,0)))*100 as IR
                from redirects,projects
                where redirects.rid=projects.rid and state<>"test" group by name order by cid desc

【问题讨论】:

    标签: php mysql sql optimization


    【解决方案1】:

    SQL 性能通常不是由于select 子句中的计算。您需要查看fromgroup by 子句。

    您的表是否有适当的索引?您应该在redirects.ridprojects.rid 或两者上都有一个索引。事实上,这些可能应该是复合索引,包括statetest(在合适的地方)。

    group by 可能是 MySQL 中的性能猪。每张表有多少数据?

    【讨论】:

    • 数据相当大,redirects 表每月大约有 200k 到 300k 条记录,但项目只有大约 30 条。 --projects.rid 是唯一索引的,redirects.rid 是索引的。我现在将索引状态,我在上面的代码中(不是在我的服务器上)出错,它应该是 state"test"
    • 索引后,脚本需要 20 秒,而不是前面提到的 30 秒。
    • 我的猜测是大部分工作都在group by 的文件排序中。您可以使用explain 看到这一点。您似乎没有任何过滤可以显着减少数据的大小。如果这很重要,您可能需要创建一个汇总表,以便与触发器保持同步。
    • 好像是这样。是否没有优化以使这项工作在不需要额外的表的情况下更好?
    猜你喜欢
    • 1970-01-01
    • 2017-03-08
    • 2019-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-11
    • 2021-10-24
    • 1970-01-01
    相关资源
    最近更新 更多