2016-11-16 71 views
0

我有这样如何加快mysql的另一个表聚合计数?

SELECT ProductId,(SELECT COUNT(*) 
         FROM Log 
         WHERE Log.App = App.No 
         AND Log.Event = 54 
         ) 
     FROM App 
     WHERE App.cat IN (1,2,3) 

该查询返回的100万条记录的查询。问题是这个查询真的很慢。我有LOG(应用程序,事件)和应用程序(猫)索引的复合索引。是否有任何方法来加快此查询? App和日志表包含10M左右的记录

当我注释掉"SELECT COUNT(*) ...."查询超快

+0

您是_counting_记录100万次(!)。什么是实际响应时间,您对它的期望是什么? – FDavidov

回答

1

你可以尝试重写查询中使用一个连接,而不是相关子查询:

SELECT t1.ProductId, 
     COALESECE(t2.logCount, 0) 
FROM App t1 
INNER JOIN 
(
    SELECT t1.No, COUNT(*) AS logCount 
    FROM App t1 
    LEFT JOIN Log t2 
     ON t1.No = t2.App AND 
      t2.Event = 54 
    WHERE t1.cat IN (1, 2, 3) 
    GROUP BY t1.No 
) t2 
    ON t1.No = t2.No 
+0

如果你在'内部查询'中执行'内部连接'并且在'外部查询'中执行''''''''会不会更好? – Shaharyar

+0

@Shaharyar仔细观察,你会明白为什么这是不可取的。在原始查询中,他计算每条记录的计数,几乎就像一个窗口函数。 'App'中的每条记录都会出现在结果集中,即使计数为零。如果我们要'INNER JOIN',那么'App'中与任何内容不匹配的记录都会被过滤掉。这将改变OP的结果集。 –

+0

外部'INNER JOIN'是可以的,因为没有机会从App t1被过滤掉。 –

0

你可以使用JOIN。因为子查询非常慢。

SELECT ProductId, COUNT(Log.*) 
    FROM App 
    LEFT OUTER JOIN Log ON Log.App = App.No AND Log.Event = 54 
    WHERE App.cat IN (1,2,3) 
+0

这不会给出想要的结果,因为它会为整个查询生成一个计数。 –

+0

是的,我写到,可以是样本 –

相关问题