Mysql查询返工好玩

时间:2010-11-16 17:58:19

标签: php mysql

当尝试执行此查询时,我的mysql服务器cpu使用率达到100%并且页面暂停。我设置了一个索引(Client_Code,Date_Time,Time_Stamp,Activity_Code,Employee_Name,ID_Transaction)它似乎没有帮助。现在我需要不同的方式来进行此查询,因此它不会在服务器上如此繁重。以下是我需要它做的描述。为了解释它,它会在每个客户端代码下查找特定日期的最后一个条目,然后一旦找到所有条目。然后它计算Eric或Jerry有多少这样的条目。我需要看看我不熟悉的代码。谢谢你的帮助。

以下是此查询的作用

数据库信息

ID_Transaction | Client_Code | Employee_Name | Date_Time |Time_Stamp| Activity_Code  
1              | 00001       |  Eric         |  11/15/10 | 7:30AM   |  00023  
2              | 00001       |  Jerry        |  11/15/10 | 8:30AM   |  00033  
3              | 00002       |  Amy          |  11/15/10 | 9:45AM   |  00034  
4              | 00003       |  Jim          |  11/15/10 | 10:30AM  |  00063  
5              | 00003       |  Ryan         |  11/15/10 | 12:00PM  |  00063  
6              | 00003       |  bill         |  11/14/10 | 1:00pm   |  00054    
7              | 00004       |  Jim          |  11/15/10 | 1:00pm   |  00045  
8              | 00005       |  Jim          |  11/15/10 | 10:00 AM |  00045  

查询获取上面的信息并对其进行计数。通过每个client_code的最新条目。在这种情况下,查询将如下所示。在php之后。

Jerry = 1    
2               | 00001       |  Jerry        |   11/15/10 |   8:30AM |   00033     
Amy = 1   
3               | 00002       |  Amy          |   11/15/10 |   9:45AM |  00034   
Ryan = 1  
5               | 00003       | Ryan          |   11/15/10 |   12:00PM | 00063  
Jim = 2  
7               | 00004       | Jim           |   11/15/10 |   1:00pm  | 00045  
8               | 00005       | Jim           |   11/15/10 |   10:00 AM| 00045      

查询:

 SELECT m.Employee_Name, count(m.ID_Transaction)   
     FROM ( 
         SELECT DISTINCT Client_Code 
             FROM Transaction
         ) md 
         JOIN Transaction m ON 
             m.ID_Transaction = ( 
                 SELECT ID_Transaction 
                     FROM Transaction mi  
                     WHERE mi.Client_Code = md.Client_Code 
                         AND Date_Time=CURdate() 
                         AND Time_Stamp!='' 
                         AND Activity_Code!='000001'  
                     ORDER BY m.Employee_Name DESC, 
                         mi.Client_Code  DESC, 
                         mi.Date_Time DESC,  
                         mi.ID_Transaction DESC 
                     LIMIT 1 
             )   
         GROUP BY m.Employee_Name    



+----+--------------------+-------------+--------+------------------------+--------------+---------+----------------+--------+----------------------------------------------+
| id | select_type        | table       | type   | possible_keys          | key          | key_len | ref            | rows   | Extra                                        |
+----+--------------------+-------------+--------+------------------------+--------------+---------+----------------+--------+----------------------------------------------+
|  1 | PRIMARY            | <derived2>  | ALL    | [NULL]                 | [NULL]       | [NULL]  | [NULL]         |    347 | Using temporary; Using filesort              |
|  1 | PRIMARY            | m           | index  | [NULL]                 | search index | 924     | [NULL]         |  29255 | Using where; Using index; Using join buffer  |
|  3 | DEPENDENT SUBQUERY | mi          | ref    | search index,secondary | search index | 18      | md.Client_Code |   2926 | Using where; Using temporary; Using filesort |
|  2 | DERIVED            | Transaction | range  | [NULL]                 | search index | 18      | [NULL]         |     10 | Using index for group-by                     |
+----+--------------------+-------------+--------+------------------------+--------------+---------+----------------+--------+----------------------------------------------+

2 个答案:

答案 0 :(得分:1)

你应该尝试运行

EXPLAIN SELECT m.Employee_Name, count(m.ID_Transaction)   
FROM ( SELECT DISTINCT Client_Code FROM Transaction) md 
JOIN Transaction m
  ON m.ID_Transaction = ( SELECT ID_Transaction FROM Transaction mi  
                          WHERE mi.Client_Code = md.Client_Code AND
                                Date_Time=CURdate() AND 
                                Time_Stamp!='' AND 
                                Activity_Code!='000001'  
                          ORDER BY m.Employee_Name DESC,
                                   mi.Client_Code  DESC, 
                                   mi.Date_Time DESC,
                                   mi.ID_Transaction DESC LIMIT 1 
                        )  
GROUP BY m.Employee_Name

以了解查询优化器如何处理您的查询。

我注意到你在同一张桌子上打了3次。我猜这会给优化器带来一些挑战。

仅仅编写一个更简单的SQL查询然后使用PHP将其削减到您正在寻找的内容可能更有意义。

答案 1 :(得分:0)

尝试使用尺寸......

SELECT m.Employee_Name, count(m.ID_Transactions) AS transactions
    FROM Transaction AS m
    JOIN (
        SELECT sub1.Client_Code, MAX(sub1.Activity_Code) AS ActivityMax
            FROM Transactions AS sub1
            WHERE Date_Time = CURdate()
                AND Time_Stamp != ''
                AND Activity_Code != '000001'
            GROUP BY sub1.Client_Code
    ) AS m2 ON m.Client_Code = m2.Client_Code 
        AND m.Activity_Code = m2.ActivityMax
    GROUP BY m.Employee_Name