繁体   English   中英

如何对另一个表进行有效的行计数(联接)

[英]How to make an efficient Count of rows from another table (join)

我在墓地有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

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

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的主键,在这种情况下,它已经被索引了。 但是,你可以添加索引到tblcemetery_IDtblnames表为可能的性能提升:

CREATE INDEX cmtry_idx ON tblnames (tblcemetery_ID)

或者,您可以在此 group by查找fe并执行类似的操作

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

基本上,您对属于该公墓的每个名称项的总和为1,因为您根本没有对名称的兴趣,无需加入公墓详细信息表

不知道sum(1)还是count(*)更好,两者都应该起作用。

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM