mariadb MySQL慢速查询会随着时间的推移变得更慢,直到完全超时

8wigbo56  于 2023-08-05  发布在  Mysql
关注(0)|答案(1)|浏览(164)

数据库服务器:

  • 服务器:127.0.0.1通过TCP/IP
  • 服务器类型:MariaDB
  • 服务器版本:10.4.27-MariaDB
    Web服务器:
  • Apache/2.4.54(Win64)
  • PHP版本:8.1.12
  • phpMyAdmin版本:5.2.0

CPU使用率为10-15%,内存使用率为30-40%
我希望能得到一些关于如何改进或优化特定查询的指导。与选择查询并行,我有十几个负载数据查询,每10秒和30秒运行一次,用于真实的显示板。所有其他选择查询似乎运行良好,并停留在2秒以下,除了这个查询,这是好的一段时间,然后我开始看到它随着时间的推移,然后最终完全超时延迟。

SELECT
   * 
FROM
   `sfdc_chat_csat` 
   LEFT JOIN
      `sfdc_chat_review` 
      ON `sfdc_chat_csat`.`ChatKey__c` = `sfdc_chat_review`.`ChatKey` 
WHERE
   `sfdc_chat_csat`.`ChatRating__c` != '' 
   AND `sfdc_chat_csat`.`ChatRating__c` <= 6 
   AND `sfdc_chat_review`.`manager_review` IS NULL 
   AND 
   (
      `sfdc_chat_csat`.`Id` IN 
      (
         'a0b4z00000W48UyAAJ',
         'a0b4z00000W48V8AAJ',
         'a0b4z00000W4CGvAAN',
         'a0b4z00000W4CMAAA3',
         'a0b4z00000W4CRjAAN',
         'a0b4z00000W4CUTAA3',
         'a0b4z00000W4CW5AAN',
         'a0b4z00000W4DAoAAN',
         'a0b4z00000W4CEpAAN',
         'a0b4z00000W4CTaAAN'
      )
   )
   AND MONTH(`CreatedDate`) >= MONTH(now());

字符串
以下是EXPLAIN查询的结果

+-----+-------------+-------------------+----------+-----------------------+---------+
| id  | select_type | table             | type     | possible_keys         | key     |
+-----+-------------+-------------------+----------+-----------------------+---------+
| 1   | SIMPLE      | sfdc_chat_csat    | range    | PRIMARY,ChatRating__c | PRIMARY |
| 1   | SIMPLE      | sfdc_chat_review  | eq_ref   | PRIMARY               | PRIMARY |
+-----+-------------+-------------------+----------+-----------------------+---------+

continued

+---------+--------------------------------------+------+-------------------------+
| key_len | ref                                  | rows | Extra                   |
+---------+--------------------------------------+------+-------------------------+
| 122     | NULL                                 | 10   | Using where             |
| 122     | dashboard.sfdc_chat_csat.ChatKey__c  | 1    | Using where; Not exists |
+---------+--------------------------------------+------+-------------------------+


下面是表sfdc_chat_csat的表结构(10 k行数据)

+---------------------------+--------------+------+-----+---------+-------+
| Field                     | Type         | Null | Key | Default | Extra |
+---------------------------+--------------+------+-----+---------+-------+
| Id                        | varchar(40)  | NO   | PRI | NULL    |       |
| IsDeleted                 | tinyint(1)   | NO   |     | NULL    |       |
| ChatKey__c                | varchar(40)  | NO   | UNI | NULL    |       |
| ChatRating__c             | varchar(40)  | NO   | MUL | NULL    |       |
| Chat_ButtonId             | varchar(40)  | NO   | MUL | NULL    |       |
| Chat_Button__c            | varchar(40)  | NO   |     | NULL    |       |
| Chat_Transcript_Number__c | varchar(40)  | NO   |     | NULL    |       |
| Chat_Transcript_Owner__c  | varchar(40)  | NO   |     | NULL    |       |
| Comments_del__c           | varchar(255) | NO   |     | NULL    |       |
| CreatedDate               | datetime     | NO   | MUL | NULL    |       |
| Customer_Email_Address__c | varchar(40)  | NO   |     | NULL    |       |
| Customer_First_Name__c    | varchar(40)  | NO   |     | NULL    |       |
| Customer_Last_Name__c     | varchar(40)  | NO   |     | NULL    |       |
| NPS_Score__c              | varchar(40)  | NO   |     | NULL    |       |
+---------------------------+--------------+------+-----+---------+-------+


下面是sfdc_chat_review的表结构(100行数据)

+-------------------+--------------+------+-----+---------+-------+
| Field             | Type         | Null | Key | Default | Extra |
+-------------------+--------------+------+-----+---------+-------+
| ChatKey           | varchar(40)  | NO   | PRI | NULL    |       |
| chatTranscriptId  | varchar(30)  | NO   |     | NULL    |       |
| manager           | varchar(30)  | NO   |     | NULL    |       |
| manager_review    | tinyint(1)   | NO   | MUL | NULL    |       |
| manager_verdict   | varchar(30)  | NO   |     | NULL    |       |
| false_reason_code | varchar(30)  | NO   |     | NULL    |       |
| manager_comments  | varchar(500) | NO   |     | NULL    |       |
+-------------------+--------------+------+-----+---------+-------+


当我运行SHOW FULL PROCESLIST;我看到此查询的多个示例处于“正在发送数据”状态。似乎当时间达到20(20秒?),然后它们将从“进程”列表中删除。
我不知道我应该如何继续下去。

imzjd6km

imzjd6km1#

这很有可能导致性能问题:

MONTH(`CreatedDate`) >= MONTH(now())

字符串
因为MONTH()将针对每一行执行,并且将不使用CreatedDate上的索引。
相反,在CreatedDate的原始值上放置一个逻辑上等价的条件:

CreatedDate >= DATE_SUB(now(), INTERVAL DAYOFMONTH(now())-1 DAY)


CreatedDate上创建索引。
您可能会发现使用BETWEEN比使用>=性能更好:

CreatedDate BETWEEN DATE_SUB(now(), INTERVAL DAYOFMONTH(now())-1 DAY) AND now()


因为尽管它在逻辑上是相同的(不会有未来的数据),优化者会把它看作是一个封闭的范围,而不是一个开放的范围。

相关问题