php - 为什么我的 mysql 查询运行缓慢?

标签 php mysql join max

我有一个查询,它从数据库中获取第二高日期的记录。我的查询运行良好,但执行起来花费了太多时间。我怎样才能快速执行我的查询。

最佳答案

我将采取与其他人有所不同的方式...我是否遗漏了一些东西,或者除了明显的索引优化之外,您的所有联接都在查找的主键上 - 您的标准准确吗?

这就是我的意思...您的最终 WHERE 子句..

   WHERE
         r.client_id IN ( SELECT opinion_id 
                             FROM pacra_client_opinion_relations
                            WHERE client_id = 50 )

您要求 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           ...

如果您的查询是 client_id = 50 的所有 OPINION_ID,您将返回 OPINION_ID #s 3、5 和 7。由于您的 where 子句在选择 Opinions 时要求 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

根据样本数据,您会得到...不同的客户可能有明显不同的第二个日期

client_id  notification_date
13         Sep 5
28         Sep 10
29         Sep 4 
50         Sep 12

如果您在 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

可以调整为...

 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

它只会返回第 50 个客户的单条记录,而所有客户的日期都是如此

client_id  notification_date
50         Sep 12

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

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

如果我的假设是准确的,还可以进行更简化的查询,我只是想解释我认为有问题的不同部分……最后,正如您所看到的示例数据,如果您可以准备关于现在和 future 的样本数据以及您想要获得的东西可能会有所帮助...

关于php - 为什么我的 mysql 查询运行缓慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32629305/

相关文章:

mysql - 左加入。字段列表中的列 'product_id' 不明确

php - 从 php/mysql 中的一系列日期中选择每月数据

php - cometd 是如何工作的?如何编写个人对个人的 cometd 聊天应用程序

php - 添加不受 Sonata Admin Bundle 管理的实体

php - imagettftext() 函数不起作用?

Mysql 选择别名列

php - 单选按钮值未存储在数据库中

sql - 聚合函数或 GROUP BY 子句

SQL INNER JOIN 与 Where Exists 性能考虑

php - CodeIgniter 中的完全动态 URL