为什么我的mysql查询工作缓慢?

sun*_*nny 5 php mysql join max

我有一个查询从db获取第二高日期的记录.我的查询运行良好,但执行时间过长.我怎样才能快速执行我的查询.

DRa*_*app 2

我的看法与其他人有点不同......我是否遗漏了一些东西,或者除了明显的索引优化之外,您的所有连接都位于查找的主键上 - 您的标准准确吗?

这就是我的意思...你的最后一个 WHERE 子句..

   WHERE
         r.client_id IN ( SELECT opinion_id 
                             FROM pacra_client_opinion_relations
                            WHERE client_id = 50 )
Run Code Online (Sandbox Code Playgroud)

您要求 CLIENT_ID 位于 OPINION_ID 的选择结果中,但仅查找 client_ID = 50 的意见。Opinion_id 的上下文是什么。

表“pacra_client_opinion_relations”中客户与意见的澄清让我们看一下示例数据,如下所示

Opinion_ID    Client_ID   Other...
1             28          ...
2             35          ...
3             50          ...
4             2           ...
5             50          ...
6             6           ...
7             50          ...
8             4           ...
Run Code Online (Sandbox Code Playgroud)

如果您的查询是 client_id = 50 的所有 OPINION_ID,则您将返回 OPINION_ID #s 3、5 和 7。由于您的 where 子句要求在选择意见中提供 CLIENT_ID,因此您现在正在获取客户端 3、5 和 7 的数据与您最初开始关注的客户 #50 无关。

另外...如果您只查找“Client_ID = 50”中的内容,那么您之前的查询试图获取第二个最近的通知日期,那么您正在查询所有客户端。如果您为“Client_ID = 50”添加 where 子句,那么您将只能收到这些通知,而不会收到所有客户端的第二个到最近的通知。

澄清 MAX() 小于内部 MAX()。来自评级的前数据您将得到以下...

og_ratings (assuming this data is pre-sorted per client for sample purposes)
client_id  notification_date
13         Sep 5      <- You want THIS entry if it was client 13 included
13         Sep 14     <- Most recent for client 13
28         Sep 1
28         Sep 8
28         Sep 10     <- You want THIS entry if client 28 included
28         Sep 11     <- Most recent for client 28
29         Sep 4      <- You want THIS entry if client 29 included
29         Sep 11     <- Most recent for client 29
43         Sep 16     <- Most recent for client 43 and no prior, 
                         this would never show as only one entry for client
50         Sep 2
50         Sep 9
50         Sep 12     <- You want THIS entry for client 50
50         Sep 15     <- Most recent for client 50
Run Code Online (Sandbox Code Playgroud)

根据样本数据,您会得到...不同的客户可能有与最新日期截然不同的第二个日期

client_id  notification_date
13         Sep 5
28         Sep 10
29         Sep 4 
50         Sep 12
Run Code Online (Sandbox Code Playgroud)

如果您在 OUTERMOST 查询中只关心客户端 50,而您的实际数据有数百个客户端(甚至数千个客户端),那么您正在查询所有客户端。您可以通过以下方式专门限制您的内部查询:客户端 50

 og_ratings r INNER JOIN (
    SELECT 
      client_id, 
      max(notification_date) notification_2nd_date
   FROM 
      og_ratings
   WHERE
      (client_id, notification_date) 
         NOT IN ( SELECT client_id, max(notification_date)
                     FROM og_ratings 
                     GROUP BY client_id )
   GROUP BY 
      client_id
   ORDER BY
      client_id DESC
Run Code Online (Sandbox Code Playgroud)

可以调整为...

 og_ratings r INNER JOIN (
    SELECT 
      client_id, 
      max(notification_date) notification_2nd_date
   FROM 
      og_ratings
   WHERE
      client_id = 50    <--- ADDED TO WHERE CLAUSE for CLIENT 50 ONLY
      AND (client_id, notification_date) 
         NOT IN ( SELECT client_id, max(notification_date)
                     FROM og_ratings 
                     WHERE client_id = 50    <--- ADDED HERE TOO FOR CLIENT 50
                     GROUP BY client_id )
   GROUP BY 
      client_id
   ORDER BY
      client_id DESC
Run Code Online (Sandbox Code Playgroud)

它只会返回客户 50 的单个记录,而不返回所有客户的日期

client_id  notification_date
50         Sep 12
Run Code Online (Sandbox Code Playgroud)

最后,在多次提供 MySQL 查询时,我都建议使用关键字 STRAIGHT_JOIN。这基本上告诉MySQL按照你告诉它的顺序进行查询...有时,当(例如你的情况),你有一堆查找表时,它可能会尝试为你考虑并首先使用查找表,因为低它应用查询的记录计数(或什么/无论如何)。

SELECT STRAIGHT_JOIN ...查询的其余部分

如果我的假设准确,也可以进行更简化的查询,我只是想解释我认为有问题的不同部分......最后,当您看到我拥有的示例数据时,如果您可以准备示例关于您所拥有的和您想要获得的当前和未来的数据可能会有所帮助......