2017-10-18 30 views
0

我有一个在墓地里有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 
+1

很难没有看到一个解释说做cemetaries,但如果我不得不冒险猜测,我会说确保你用来加入你的子查询的两个字段被索引。 – JNevill

+0

是的,对不起,在每个公墓 –

回答

2

你可以修改你的查询,使用联接,而不是相关子查询:

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) 
+0

这意味着你预计有一个墓地,没有人埋在里面。 – Strawberry

+0

@Strawberry美国有很多人使用mort房和墓地作为所得税诈骗。如果在那里有几个实际上并没有死人的墓地,我也​​不会感到惊讶。 –

+0

......或者我想的宠物墓地。 – Strawberry

0

或者你可以查找group byhere f.e.,并完成类似

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

你基本上每个总结1因为你根本没有名字,所以不需要加入公墓详细表

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

刹那间只得到有PPL里面虽然

0

我们甚至可以不用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 
相关问题