简体   繁体   English

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

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

I have a database of 100,000 names in cemeteries. 我在墓地有100,000个名字的数据库。 The cemeteries number around 6000....i wish to return the number of names in each cemetery.. 墓地的数目大约为6000 ..我希望返回每个墓地中的名字数目。

If i do an individual query, it takes a millisecond 如果我进行单个查询,则需要一毫秒

SELECT COUNT(*) FROM tblnames
    WHERE tblcemetery_ID = 2 

My actual query goes on and on and I end up killing it so I dont kill our database. 我的实际查询不断进行,最终导致它被杀死,所以我不杀死我们的数据库。 Can someone point me at a more efficient method? 有人可以指出我一种更有效的方法吗?

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

You can rephrase your query to use a join instead of a correlated subquery: 您可以将查询改写为使用联接而不是相关子查询:

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

I have heard that in certain databases, such as Oracle, the optimizer is smart enough to figure out what I wrote above, and would refactor your query under the hood. 我听说在某些数据库(例如Oracle)中,优化器足够聪明,可以弄清楚我上面写的内容,并且可以在后台重构您的查询。 But the MySQL optimizer might not be smart enough to do this. 但是MySQL优化器可能不够聪明。

One nice side effect of this refactor is that we now see an opportunity to improve performance even more, by adding indices to the join columns. 这种重构的一个很好的副作用是,我们现在看到了通过向联接列添加索引来进一步提高性能的机会。 I am assuming that id is the primary key of tblcemetery , in which case it is already indexed. 我假设idtblcemetery的主键,在这种情况下,它已经被索引了。 But you could add an index to tblcemetery_ID in the tblnames table for a possible performance boost: 但是,你可以添加索引到tblcemetery_IDtblnames表为可能的性能提升:

CREATE INDEX cmtry_idx ON tblnames (tblcemetery_ID)

Or you could look up group by here fe and do something like 或者,您可以在此 group by查找fe并执行类似的操作

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

You essentially sum up 1 for each name entry that belongs to this cemetery as you are not interessted in the names at all, no need to join to the cemetary detail table 基本上,您对属于该公墓的每个名称项的总和为1,因为您根本没有对名称的兴趣,无需加入公墓详细信息表

Not sure if sum(1) or count(*) is better, both should work. 不知道sum(1)还是count(*)更好,两者都应该起作用。

Youll only get cemetaries that have ppl inside though 虽然你只会得到里面有ppl的墓地

It could even be done without a JOIN by using an EXISTS clause like this 使用这样的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