【问题标题】:How to make an efficient Count of rows from another table (join)如何对另一个表中的行进行有效计数(连接)
【发布时间】:2017-10-18 15:12:54
【问题描述】:

我有一个包含 100,000 个墓地名字的数据库。墓地数量在 6000 左右....我希望返回每个墓地的名字数量..

如果我做一个单独的查询,它需要一毫秒

SELECT COUNT(*) FROM tblnames
    WHERE tblcemetery_ID = 2 

我的实际查询一直在继续,我最终杀死了它,所以我没有杀死我们的数据库。有人能指点我一个更有效的方法吗?

select tblcemetery.id,
  (SELECT COUNT(*) FROM tblnames
        WHERE tblcemetery_ID = tblcemetery.id) AS casualtyCount
    from tblcemetery                                                      
      ORDER BY
   fldcemetery

【问题讨论】:

  • 很难说没有解释,但如果我不得不冒险猜测,我会说确保您用于加入子查询的两个字段已编入索引。
  • 是的,对不起,在每个墓地

标签: mysql join count


【解决方案1】:

您可以改写查询以使用连接而不是相关子查询:

SELECT
    t1.id,
    COUNT(t2.tblcemetery_ID) AS casualtyCount
FROM tblcemetery t1
LEFT JOIN tblnames t2
    ON t1.id = t2.tblcemetery_ID
GROUP BY
    t1.id
ORDER BY
    t1.id

我听说在某些数据库中,例如 Oracle,优化器足够聪明,可以找出我上面写的内容,并且会在后台重构您的查询。但是 MySQL 优化器可能不够聪明,无法做到这一点。

此重构的一个很好的副作用是,我们现在看到了通过向连接列添加索引来进一步提高性能的机会。我假设idtblcemetery 的主键,在这种情况下它已经被索引了。但是您可以在tblnames 表中为tblcemetery_ID 添加索引,以提高性能:

CREATE INDEX cmtry_idx ON tblnames (tblcemetery_ID)

【讨论】:

  • 这意味着你预计会有一个没有人埋在里面的墓地。
  • @Strawberry 在美国,很多人使用太平间和墓地来骗取所得税。如果那里有几个墓地实际上并没有死人,我不会感到惊讶。
  • ...或者我想的宠物墓地。
  • 我添加了索引,查询在 0.219 秒内运行!谢谢
【解决方案2】:

它甚至可以在没有JOIN 的情况下通过使用像这样的EXISTS 子句来完成

SELECT id, COUNT(*) AS casualtyCount
FROM tblcemetery
WHERE EXISTS (SELECT 1 FROM tblnames WHERE tblcemetery_ID=id)
GROUP BY id
ORDER BY id

【讨论】:

    【解决方案3】:

    或者您可以查找 group by here f.e. 并执行类似的操作

       SELECT tblcemetery_ID,  sum(1) from tblnames group by tblscemetery_id
    

    您基本上为属于此墓地的每个名称条目总结 1,因为您根本对名称不感兴趣,无需加入墓地详细信息表

    不确定sum(1)count(*) 是否更好,两者都应该工作。

    你只会得到里面有 ppl 的墓地

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-13
      • 2015-08-16
      相关资源
      最近更新 更多