Mysql 使用2个左连接计数()执行查询需要30秒

Mysql 使用2个左连接计数()执行查询需要30秒,mysql,Mysql,我有以下三个表格: 赠品\u步骤\u完成 赠品及参赛作品 赠品步骤 赠品\u步骤\u完成 id step_unique_alone 赠品及参赛作品 id giveaway_step_unique 赠品步骤 id step_unique_alone 查询列出了赠品步骤中的所有记录,然后仅基于步骤对赠品步骤记录进行计数。之后,它根据giveways\u step\u unique统计giveways\u条目记录 SQL查询运行良好,但方式不正确,因为执行和显示需要

我有以下三个表格:

  • 赠品\u步骤\u完成
  • 赠品及参赛作品
  • 赠品步骤
  • 赠品\u步骤\u完成

    id      step_unique_alone
    
    赠品及参赛作品

    id      giveaway_step_unique
    
    赠品步骤

    id      step_unique_alone
    
    查询列出了
    赠品步骤
    中的所有记录,然后仅基于
    步骤
    赠品步骤
    记录进行计数。之后,它根据
    giveways\u step\u unique
    统计
    giveways\u条目
    记录

    SQL查询运行良好,但方式不正确,因为执行和显示需要30秒

    giveaway\u steps\u done
    有7000条记录。
    giveaways\u条目
    有6800条记录。
    giveaway\u步骤
    有170条记录

    查询:

    SELECT giveaway_steps.*, 
           Count(DISTINCT giveaway_steps_done.id) AS total_steps_count, 
           Count(DISTINCT giveaways_entries.id)   AS total_steps_correct_count 
    FROM   giveaway_steps 
           LEFT JOIN giveaway_steps_done 
                  ON ( giveaway_steps_done.step_unique_alone = 
                       giveaway_steps.step_unique_alone ) 
           LEFT JOIN giveaways_entries 
                  ON ( giveaways_entries.giveaway_step_unique = 
                       giveaway_steps.step_unique_alone ) 
    GROUP  BY giveaway_steps.id 
    ORDER  BY giveaway_steps.id DESC 
    
    样本/预期

    id       (giveaway_steps details)  total_steps_count    total_steps_correct_count 
    1        blabla  3                                      3
    2        blabla  5                                      1
    3        blabla  34                                     22
    4        blabla  52                                     53
    5        blabla  13                                     10
    
    数据是正确的,但需要很多时间。我只是想做一个更好的费时费力的查询

    如何重做问题:

  • 如上所述创建三个表
  • 如上所述添加COL
  • 将10/15条记录添加到
    giveaway\u步骤
    ,单独使用不同的
    步骤
  • 将随机数据添加到其他表中,它们的
    step\u unique\u单独
    /
    giveaway\u step\u unique
    必须与
    giveaway\u steps
    中的其中一条记录相匹配
    *问题是,使用LEFT JOIN和COUNT()查询需要时间。

    此连接效率低下,因为它复制了大量数据

    假设
    giveaway\u步骤。仅步骤\u unique\u
    是唯一的,并且
    giveaway\u步骤\u完成。仅步骤\u unique\u
    giveaways\u条目。giveaway\u步骤\u unique
    是引用该列的外键。然后在
    giveaway\u steps\u done
    表中有7000/170行,在
    giveaway\u条目中有6800/170行。您的联接将在每个“步骤”中产生大约(7000/170)*(6800/170)行。这是总的(7000/170)*(6800/170)*170,大约是280K行。但即使有280K行,也不需要30秒来执行。所以我猜您错过了支持联接的索引

    为了避免这种巨大的连接,我将在SELECT子句中计算子查询中的相关行:

    SELECT giveaway_steps.*, 
        (
            SELECT Count(giveaway_steps_done.id)
            FROM giveaway_steps_done
            WHERE giveaway_steps_done.step_unique_alone = giveaway_steps.step_unique_alone
        ) AS total_steps_count,
        (
            SELECT Count(giveaways_entries.id)
            FROM giveaways_entries
            WHERE giveaways_entries.giveaway_step_unique = giveaway_steps.step_unique_alone
        ) AS total_steps_correct_count 
    FROM giveaway_steps
    ORDER BY giveaway_steps.id DESC
    

    确保你有
    giveways\u steps\u done.step\u unique\u one
    giveways\u条目的索引。giveways\u step\u unique

    嗯?为什么要投否决票?我已经解释了整个问题并提供了查询?我不知道为什么有人否决了您的问题,但您应该查看SQL问题指南:我猜是示例,但如问题中所述。示例并不重要,因为问题在于查询需要很多时间,而不是预期的输出不正确。此表上的主键是什么?它有其他索引吗?至少发布CREATE语句。我已经尝试过这个查询。来自左联接的结果生成所有步骤(170),其中包含
    总步骤计数
    总步骤计数
    的信息。根据你的查询,我只有15条记录,而不是全部170条记录。这15条记录确实有一个“0”值,并且是正确的,因此问题不是“空值记录”。@Jaeger“使用您的查询,我只有15条记录,而不是所有170条记录”-这是不可能的。我的查询没有WHERE(或HAVING)子句,因此它应该返回
    giveaway\u步骤中的所有行。我的慢速查询:。你的问题:我应该在你的截图上看到什么?有超过15排。我看到的唯一区别是顺序。在我的查询中添加
    ORDER BY giveway\u steps.id DESC
    。很抱歉,因为我添加了新的步骤。不同之处在于,慢速查询包含整个170个步骤,而您的查询最多不包含20-25条记录,而不包含整个记录。添加您的建议后,结果仍然是一样的,没有任何变化,只是顺序发生了变化,我认为这与获取记录无关。