优化来自 MySQL SP/触发器/函数的查询

Abd*_*naf 5 mysql trigger stored-procedures functions

我必须调查一个 MySQL 生产服务器,在调查时我发现一个DELETE查询的状态"SHOW PROCESSLIST"超过 400 秒preparing我试图在慢日志中找到查询,但我无法在慢日志中找到查询。

mysql> show full processlist;
+------+-----------------+---------------------+-----------+---------+------+-----------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Id   | User            | Host                | db        | Command | Time | State                       | Info                                                                                                                                                                                                                                                                                                         |
+------+-----------------+---------------------+-----------+---------+------+-----------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|    2 | event_scheduler | localhost           | NULL      | Daemon  |  204 | Waiting for next activation | NULL                                                                                                                                                                                                                                                                                                         | 
| 7229 | root            | 192.168.1.178       | mydb      | Connect |  204 | preparing                   | DELETE
          FROM    TEST_DATA_1
         WHERE ID in
                (SELECT ID
                   FROM TEST_DATA_2
                  WHERE STATE >= 16384
                    AND (MODIFY_DT IS NULL or MODIFY_DT <= ADDDATE(SYSDATE(), INTERVAL -10 MINUTE))) | 
+------+-----------------+---------------------+-----------+---------+------+-----------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
Run Code Online (Sandbox Code Playgroud)

我将其转换为相应的 SELECT 并执行。180 secs执行花了很多时间,我观察到它处于preparing状态很长时间。

我将相同的SELECT子查询转换为JOIN它在几分之一秒内执行。所以我想我可以优化查询。

经过一番分析,我发现查询是写在 a 里面的procedure所以我的问题是如果一个查询写MySQL SP/Triggers/Functions/Events得很慢,它不会被记录到慢日志文件中。

我们是否需要SP/Triggers/Functions/Events单独优化每个?我有大约 300 多个 SP、40 多个触发器以及一些事件,因此我需要独立优化它们。

2013 年 12 月 31 日更新

  1. 如果一个过程花费的时间比慢日志时间长,它应该被记录到慢日志中CALL ProcedureName(),但是这不会发生,为什么慢日志中没有调用语句?

  2. 为什么查询在准备状态上花费了大量时间?从MySQL Doc 通用线程状态我发现preparing state声明为

准备

此状态发生在查询优化期间。

我希望我可以将删除查询重写为

DELETE A.* FROM 
TEST_DATA_1 A 
INNER JOIN 
TEST_DATA_2 B ON A.ID = B.ID 
WHERE B.STATE >= 16384 AND (B.MODIFY_DT IS NULL or B.MODIFY_DT <= ADDDATE(SYSDATE(), INTERVAL -10 MINUTE)) 
Run Code Online (Sandbox Code Playgroud)

可以吗?

Shl*_*ach 5

你实际上问了两个问题:

  1. “如果一个查询写在 MySQL SP/Triggers/Functions/Events 中很慢,它不会被记录到慢日志文件中”

    答:它不会登录到标准的 MySQL 服务器中。请查看 Percona Server扩展以获取慢速日志:特别是查看log_slow_sp_statements配置变量。它可以满足您的需求:记录例程中的慢查询。请注意,这不适用于触发器。

  2. “我们是否需要单独优化每个 SP/触发器/函数/事件?”

    回答:嗯,当然。每个查询都需要尽可能优化,具体取决于您的要求。例程不是导致内部查询运行得更快的“神奇解决方案”......