programing

Mysql 로드의 임의 피크가 모든 사용자를 느리게 함

bestprogram 2023. 6. 11. 11:06

Mysql 로드의 임의 피크가 모든 사용자를 느리게 함

우리는 지난 2년 동안 꽤 잘 작동하는 사이트를 가지고 있습니다.그러나 실제로 데이터베이스 로드에서 랜덤 피크가 발생하여 사이트 속도가 몇 초 동안 매우 느려지는 것을 볼 수 있습니다.

이러한 피크는 서버의 특정 부하에서만 나타나며 예측이 불가능합니다.더 많은 사용자 = 더 많은 피크.이러한 피크 이외에서는 모든 작업이 매우 원활하게 실행됩니다(페이지 로드는 300ms 미만).CPU와 RAM은 이러한 피크의 영향을 받지 않습니다.

스파이크는 100개의 연결에서 1000개의 연결로 2초 또는 3초 동안 이동할 수 있기 때문에 특히 DB 연결에서 볼 수 있습니다.다시 정상으로 돌아옵니다.

PHP 로그에는 아무것도, 느린 쿼리 로그에는 아무것도 없습니다(long_http_time = 0.1).

Server : Debian / MariaDB 10.3.31, Apache 2.4.38, PHP 7.3.31 모든 테이블은 기본 키를 가진 InnoDB입니다.소켓에 의한 연결.코드 점화기 4.1.7. Redis 캐시입니다.

이미 시도한 내용:

서버 재부팅 / Mysql 재시작

24시간 동안 long_message_time = 0인 느린 쿼리 로그를 실행한 후 결과에 pt-message-message를 실행합니다.모든 것이 괜찮습니다.

트래픽이 많은 경우 3시간 동안 일반 로그를 기록한 후 결과에 대해 pt-query-digest를 수행합니다.모든 것이 괜찮습니다.

로그의 각 요청에 대해 설명합니다.모두 괜찮아 보인다.

문제의 원인을 찾기 위해 어디를 찾아야 할지 더 이상 알 수 없습니다.

추가 정보:

환경 : VMware 가상 머신 | CPU : 16x Intel(R) Xeon(R) Gold 6240R CPU @ 2.40GHz | RAM : 31.39 GiB | Disk : SAN 네트워크를 통한 SSD

SHOW VARIABLES: https://pastebin.com/fx99mrdt

SHOW GLOBAL STATUTS: https://pastebin.com/NY1PKqpp

SHOW ENGINE INNODB STATUS: https://pastebin.com/bNcKKTYN

MYSQL TUNNER: https://pastebin.com/8gx9Qp1j

편집 1:

EXPLAIN UPDATE *******.eleves_tchat
     SET lu = 'true'
     WHERE id_etablissement = '266'
       AND id_eleve = '512385'
       AND auteur = 'enseignant'
       AND lu = 'false';

 id | select_type | table        | type        | possible_keys                                                      | key                                                             | key_len | ref  | rows | Extra
----|-------------|--------------|-------------|--------------------------------------------------------------------|-----------------------------------------------------------------|---------|------|------|-----------------------------------------------------------------------------------------------
 1  | SIMPLE      | eleves_tchat | index_merge | fk_te_eleves_tchat_id_etablissement,lu,fk_te_eleves_tchat_id_eleve | fk_te_eleves_tchat_id_eleve,fk_te_eleves_tchat_id_etablissement | 4,4     | NULL | 1    | Using intersect(fk_te_eleves_tchat_id_eleve,fk_te_eleves_tchat_id_etablissement); Using where

편집 2:

SHOW CREATE TABLE eleves_tchat;

CREATE TABLE `eleves_tchat` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `date` datetime NOT NULL,
 `id_etablissement` int(11) NOT NULL,
 `id_eleve` int(11) NOT NULL,
 `auteur` enum('eleve','enseignant') NOT NULL,
 `message` text NOT NULL,
 `lu` enum('false','true') NOT NULL,
 PRIMARY KEY (`id`),
 KEY `fk_te_eleves_tchat_id_etablissement` (`id_etablissement`),
 KEY `lu` (`lu`),
 KEY `fk_te_eleves_tchat_id_eleve` (`id_eleve`),
 CONSTRAINT `fk_te_eleves_tchat_id_eleve` FOREIGN KEY (`id_eleve`) REFERENCES `eleves` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
 CONSTRAINT `fk_te_eleves_tchat_id_etablissement` FOREIGN KEY (`id_etablissement`) REFERENCES `mydomain_common`.`etablissements` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=610190 DEFAULT CHARSET=latin1


SHOW TABLE STATUS FROM mydomain_enseignant WHERE name = 'eleves_tchat'

+--------------+--------+---------+------------+-------+----------------+-------------+-----------------+--------------+-----------+----------------+------------------+------------------+------------+-------------------+----------+----------------+---------+------------------+-----------+
|     Name     | Engine | Version | Row_format | Rows  | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment |   Create_time    |   Update_time    | Check_time |     Collation     | Checksum | Create_options | Comment | Max_index_length | Temporary |
+--------------+--------+---------+------------+-------+----------------+-------------+-----------------+--------------+-----------+----------------+------------------+------------------+------------+-------------------+----------+----------------+---------+------------------+-----------+
| eleves_tchat | InnoDB |      10 | Dynamic    | 64917 |            105 |     6832128 |               0 |      4374528 |   4194304 |         610189 | 17/01/2022 10:10 | 07/03/2022 10:29 | NULL       | latin1_swedish_ci | NULL     |                |         |                0 | N         |
+--------------+--------+---------+------------+-------+----------------+-------------+-----------------+--------------+-----------+----------------+------------------+------------------+------------+-------------------+----------+----------------+---------+------------------+-----------+

편집 3:

복합 인덱스와 OPTIMIZE'leves_tchat 테이블을 사용합니다.

EXPLAIN UPDATE mydomain_enseignant.eleves_tchat SET lu = 'true' WHERE id_etablissement = '266' AND id_eleve = '512385' AND auteur = 'enseignant' AND lu = 'false';

+----+-------------+--------------+-------+-------------------------------------------------------+-------------------------------------+---------+------+------+---------------------------+
| id | select_type |    table     | type  |                     possible_keys                     |                 key                 | key_len | ref  | rows |           Extra           |
+----+-------------+--------------+-------+-------------------------------------------------------+-------------------------------------+---------+------+------+---------------------------+
|  1 | SIMPLE      | eleves_tchat | range | fk_te_eleves_tchat_id_eleve,id_etablissement_id_el... | id_etablissement_id_eleve_auteur_lu |      10 | NULL |    1 | Using where; Using buffer |
+----+-------------+--------------+-------+-------------------------------------------------------+-------------------------------------+---------+------+------+---------------------------+

SHOW TABLE STATUS FROM mydomain_enseignant WHERE name = 'eleves_tchat'

+--------------+--------+---------+------------+-------+----------------+-------------+-----------------+--------------+-----------+----------------+------------------+------------------+------------+-------------------+----------+----------------+---------+------------------+-----------+
|     Name     | Engine | Version | Row_format | Rows  | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment |   Create_time    |   Update_time    | Check_time |     Collation     | Checksum | Create_options | Comment | Max_index_length | Temporary |
+--------------+--------+---------+------------+-------+----------------+-------------+-----------------+--------------+-----------+----------------+------------------+------------------+------------+-------------------+----------+----------------+---------+------------------+-----------+
| eleves_tchat | InnoDB |      10 | Dynamic    | 62117 |            126 |     7880704 |               0 |      3178496 |   4194304 |         611015 | 07/03/2022 18:09 | 07/03/2022 18:20 | NULL       | latin1_swedish_ci | NULL     |                |         |                0 | N         |
+--------------+--------+---------+------------+-------+----------------+-------------+-----------------+--------------+-----------+----------------+------------------+------------------+------------+-------------------+----------+----------------+---------+------------------+-----------+

편집 4:

우리는 우리 앱에서 거래를 사용하지 않습니다. ROLLBACKs의 발다니합생에 의해 합니다.check_mysql_health다음과 같은 정기적인 요청을 전송하여 데이터베이스를 모니터링하는 Nagios용 플러그인:

35211159 Query  SET autocommit=0
35211159 Query  SHOW VARIABLES LIKE 'version'
35211159 Query  SHOW STATUS LIKE 'Uptime'
35211159 Query  SHOW VARIABLES LIKE 'have_innodb'
35211159 Query  SHOW /*!50000 global */ STATUS LIKE 'Innodb_buffer_pool_wait_free'
35211159 Query  ROLLBACK
35211159 Quit

편집 5:

첫 번째 질문 이후 다음을 사용하여 구성을 업데이트합니다.

innodb_io_capacity = 1000
innodb_flush_neighbors = 0

에 있기 에, 에 이크는항있여때문에기기에상스파,▁the▁is▁spikes때에문있▁here,pt-query-digest느림.에 하루느보의가 있는long_query_time = 0일부 쿼리는 30초 이상 걸리지만 매일 SQL 덤프 백업을 수행하는 동안에만 실행됩니다.

pt_query_slow_log: https://pastebin.com/hKvz37ca

편집 6:

SHOW CREATE TABLE PASSATIONS;

CREATE TABLE `passations` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `id_eleve` int(11) NOT NULL,
 `id_module` tinyint(2) NOT NULL,
 `type_seance` enum('normale','inversee','tutore') NOT NULL,
 `id_item` int(11) NOT NULL,
 `date` date NOT NULL,
 `heure` time NOT NULL,
 `format_question` enum('qcm','ouvert') NOT NULL,
 `type_question` enum('preparatoire','principale') NOT NULL,
 `duree` smallint(5) unsigned NOT NULL,
 `score` tinyint(1) NOT NULL,
 `correction` enum('0','1') NOT NULL,
 `premier` tinyint(1) NOT NULL,
 `num_reponse` tinyint(1) NOT NULL,
 `reponses` varchar(255) NOT NULL,
 `justification` varchar(2000) NOT NULL,
 `age` float NOT NULL,
 `methode` enum('evaluation','entrainement') NOT NULL,
 `niveau` tinyint(2) NOT NULL,
 `num_eval` tinyint(1) NOT NULL,
 `timestamp_entrainement` bigint(20) unsigned NOT NULL,
 `mots_bleus` enum('false','true') NOT NULL,
 `question_preparatoire` enum('false','true') NOT NULL,
 `lecture_audio` enum('false','true') NOT NULL,
 `id_binome` int(11) NOT NULL,
 `font_size` enum('14','16','18','20') NOT NULL,
 `line_height` enum('25','30','35') NOT NULL,
 `letter_spacing` enum('0','1','2') NOT NULL,
 `word_spacing` enum('0','5','10','15') NOT NULL,
 `font_family` enum('1','2','3','4') NOT NULL,
 `lire_couleur` enum('normal','syllabes','phonemes','muettes') NOT NULL,
 `phonemes` text NOT NULL,
 `expe` varchar(10) NOT NULL,
 PRIMARY KEY (`id`),
 KEY `fk_te_passations_id_item` (`id_item`),
 KEY `fk_te_passations_id_module` (`id_module`),
 KEY `fk_te_passations_id_eleve` (`id_eleve`),
 KEY `id_eleve_id_module_premier_methode_type_seance_type_question` (`id_eleve`,`id_module`,`premier`,`methode`,`type_seance`,`type_question`) USING BTREE,
 CONSTRAINT `fk_te_passations_id_eleve` FOREIGN KEY (`id_eleve`) REFERENCES `eleves` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
 CONSTRAINT `fk_te_passations_id_item` FOREIGN KEY (`id_item`) REFERENCES `my_domain_common`.`items` (`id`) ON UPDATE CASCADE,
 CONSTRAINT `fk_te_passations_id_module` FOREIGN KEY (`id_module`) REFERENCES `my_domain_common`.`modules` (`id`) ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=81067688 DEFAULT CHARSET=latin1

EXPLAIN SELECT MAX(`id`) AS `id` FROM my_domain_enseignant.passations WHERE `id_eleve` IN ('499613','499611','499612','499614', '499615','499616','499617','499618','499619','499620', '499621','499622','499623','499624','499625','499626', '499627','499628','499629','499630','499631','499632', '499633','499634' ) AND `id_module` = '1' AND `type_seance` = 'normale' AND `type_question` = 'principale' AND `methode` = 'entrainement' AND `premier` = 1
  
+----+-------------+------------+-------+-------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------+---------+------+------+--------------------------+
| id | select_type |   table    | type  |                                                   possible_keys                                                   |                             key                              | key_len | ref  | rows |          Extra           |
+----+-------------+------------+-------+-------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------+---------+------+------+--------------------------+
|  1 | SIMPLE      | passations | range | fk_te_passations_id_module,fk_te_passations_id_eleve,id_eleve_id_module_premier_methode_type_seance_type_question | id_eleve_id_module_premier_methode_type_seance_type_question |       9 | NULL |  910 | Using where; Using index |
+----+-------------+------------+-------+-------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------+---------+------+------+--------------------------+

편집 7:

온라인 사용자가 500명에 이를 때 어떤 일이 일어나고 있는지 설명하고자 했습니다.이미지 1에서는 모든 것이 정상이며, 평균 페이지 로드는 300ms 미만입니다.그리고 나서 당신은 이미지 2에서 모든 사용자의 속도를 늦추고 3초에 걸쳐 페이지 로드를 만드는 큰 스파이크를 볼 수 있습니다.

모든 것이 괜찮습니다 --------> 그럼 BOM!

우리는 아마도 우리의 문제의 원인을 찾았을 것입니다.이것은 Codeigniter 4에서 Redis Handler를 동시 Ajax 요청과 함께 사용할 때 PHP 세션의 잠금 메커니즘과 관련이 있는 것 같습니다.

Redis에서 File 세션으로 이동한 후 스파이크가 더 이상 나타나지 않고 모든 것이 원활하게 실행됩니다.

자세한 내용은 Codeigniter 4 github: https://github.com/codeigniter4/CodeIgniter4/issues/4391 에서 공개된 이 문제를 참조하십시오.

도와주신 모든 분들께 감사드립니다!

복합 인덱스보다 효율성이 떨어집니다.

다음 4개의 열을 가진 인덱스를 임의의 순서로 지정합니다.

(id_etablissement, id_eleve, auteur, lu)

복합 인덱스를 추가할 때 선행 열이 동일한 Drop 인덱스.즉, INDEX(a)와 INDEX(a,b)가 모두 있는 경우 전자를 던집니다.


Analysis of GLOBAL STATUS and VARIABLES:
 

관측치:

  • 버전: 10.3.31-MariaDB-0+deb10u1-log
  • 31.39GB RAM
  • 가동 시간 = 35d 21:04:32
  • 87.2 QPS

더 중요한 문제:

뭐, 별로 중요한 건 아니지만,

"SAN 네트워크를 통한 SSD"가 있으므로 다음과 같은 몇 가지 설정이 도움이 될 수 있습니다.

innodb_io_capacity = 1000
innodb_flush_neighbors = 0

세트가 크기보다 것으로 , 은 RAM 크기보다 더 작은 것 . 따라서 아래의 의견은innodb_buffer_pool_size모순될 것입니다.지금은 해당 설정을 변경할 필요가 없습니다.

Max_used_connections높은 편입니다.이 문제가 가끔 발생할 경우 스파이크를 조사하는 것이 현명할 수 있습니다.빈번한 경우 유휴 연결을 닫는 등을 조사합니다.

과도한 RAM 사용을 줄이기 위한 몇 가지 설정:

tmp_table_size      = 100M
max_heap_table_size = 100M
host_cache_size = 1000
thread_pool_max_threads = 2000

기타 설정:

max_connect_errors = 1000

ㅠㅠㅠㅠROLLBACKs하지만 근본적으로 아닙니다.COMMITs사용하시겠습니까?autocommit만약 그렇다면, 어떤 가치로?(그것은ON SHOW하지만 그것은 우연일 수도 있었습니다.)

세부 정보 및 기타 관찰:

( innodb_buffer_pool_size ) = 6,144 / 33704755855.36 = 19.1%InnoDB buffer_pool에 사용되는 RAM의 % - 사용 가능한 RAM의 약 70%로 설정합니다. (낮음은 효율성이 낮으며, 스와핑 위험이 너무 높습니다.)

( innodb_lru_scan_depth * innodb_page_cleaners ) = 1,024 * 4 = 4,096초당 페이지 클리너에 대한 작업량입니다. -- "InnoDB: page_cleaner: 1000ms 의도된 루프 소요..."는 lru_scan_depth를 낮춰서 수정할 수 있습니다. 1000 / innodb_page_cleaner(현재 4개)를 고려하십시오.스왑도 확인합니다.

( innodb_lru_scan_depth ) = 1,024변수입니다.innodb_lru_scan_depth는 변수입니다. 나은 이름은 innodb_free_page_target_per_buffer_pool입니다. 및 작업 속도를 각 풀 있는 -- : : loop taked..."는 할 수 . innooper: 1000ms end: --innooper."는 lru_scan_depth를 낮춤으로써 수정될 수 있습니다.

( innodb_io_capacity ) = 200플러시할 때는 이 정도의 IOP를 사용하십시오. 읽기가 느리거나 뾰족할 수 있습니다.SSD 드라이브를 사용하는 경우 2000을 사용합니다.

( Innodb_buffer_pool_pages_free / Innodb_buffer_pool_pages_total ) = 193,281 / 393216 = 49.2%필요한 보다 큽니다.buffer_pool pct가 필요합니다. innodb_buffer_pool_size(6442450944).

( Uptime / 60 * innodb_log_file_size / Innodb_os_log_written ) = 3,099,872 / 60 * 512M / 44932925440 = 617InnoDB 로그 순환 간격(분) 5.6.8부터 innodb_log_file_size를 동적으로 변경할 수 있습니다. MariaDB에 대해서는 잘 모르겠습니다. (은 다소임의적입니다.)my.cnf의 경우에도 입니다. -- (60분 권장 사항)를 (할 수 없습니다 innodb_log_file_size(536870912)에 저장됩니다. (AWS에서는 변경할 수 없습니다.)

( innodb_flush_method ) = innodb_flush_method = fsyncInnoDB가 OS에 블록 쓰기를 요청하는 방법.O_DIRECT(Percona) O_ALL_DIRECT(Percona). () Chrischandler에서 O_ALL_DIRECTO_ALL_DIRECT 경고하는 내용은 참조하십시오.

( default_tmp_storage_engine ) = default_tmp_storage_engine =

( Innodb_row_lock_waits/Innodb_rows_inserted ) = 123,721/2791251 = 4.4%행을 기다려야 하는 빈도입니다.

( innodb_flush_neighbors ) = innodb_flush_neighbors = 1디스크에 블록을 쓸 때 사소한 최적화 - SSD 드라이브에는 0을 사용하고 HDD에는 1을 사용합니다.

( innodb_io_capacity ) = 200Disk에서 초당 I/O 작업 가능. 느린 드라이브의 경우 100회, 회전하는 드라이브의 경우 200회, SSD의 경우 1000-2000회, RAID 팩터를 곱합니다.초당 쓰기 IO 요청 수를 제한합니다.우선, HDD: 200, SSD: 2000입니다.

( innodb_adaptive_hash_index ) = innodb_adaptive_hash_index = ON 해시 -- , 는 OFF, DDL-heavy는 로 설정합니다. -- DDL-heavy는 ON, DDL-heavy는 OFF입니다.

( innodb_flush_log_at_trx_commit ) = 22 = (결정함)1 = 안보, 2 빠름사 -- (사용자가 결정함) 0)=1을 합니다.최대 수준의 내결함성을 얻으려면 sync_binlog(현재 0)=1과 함께 1을 사용합니다.속도는 0이 가장 좋습니다.2는 0과 1 사이의 절충입니다.

( sync_binlog ) = 0보안을 강화하기 위해 1을 사용하면 I/O = 1의 비용으로 인해 많은 "인스턴스 엔드"가 발생할 수 있습니다. = 0은 충돌 시 "불가능한 위치에 있는 binlog"가 발생하여 트랜잭션이 손실될 수 있지만 더 빠릅니다.Galera는 0으로 괜찮습니다.

( innodb_adaptive_hash_index ) = innodb_adaptive_hash_index = ON일반적으로 켜져야 합니다. -- 꺼짐이 더 나은 경우가 있습니다.innodb_adaptive_hash_index_parts(innodb_adaptive_hash_index_parts(5.7.9인치) innodb_adaptive_hash_index_parts(MariaDB 및 Percona) 파일입니다. 충돌. OFF로 했습니다.ON은 드문 충돌(버그 73890)에 관련되어 있습니다. 10.5.0은 기본값으로 OFF로 결정되었습니다.

( innodb_print_all_deadlocks ) = innodb_print_all_deadlocks = OFF모든 교착 상태를 기록할지 여부 - 교착 상태로 인해 문제가 발생한 경우 이 항목을 설정합니다.파일: 상태가 될 수 .교착 상태가 많은 경우 디스크에 많이 기록될 수 있습니다.

( max_connections ) = 2,000최대 연결(스레드) 수입니다.다양한 할당에 영향을 미칩니다. -- max_connections(현재 2000개)가 너무 높고 다양한 메모리 설정이 높으면 RAM이 부족할 수 있습니다.

( join_buffer_size * Max_used_connections ) = (4M * 1075) / 33704755855.36 = 13.4% 기준) -- 4194304해야 합니다 (join_buffer_size) -- join_buffer_size(4194304) RAM이 부족합니다.

( min( tmp_table_size, max_heap_table_size ) ) = (min( 500M, 500M )) / 33704755855.36 = 1.6%MEMORY 테이블(테이블당) 또는 SELECT 내부의 임시 테이블(일부 SELECT당)이 필요할 때 할당할 RAM의 백분율입니다.너무 높으면 스왑이 발생할 수 있습니다. -- tmp_table_size(현재 524288000)와 max_heap_table_size(현재 524288000)를 RAM의 1%로 줄입니다.

( local_infile ) = local_infile = ON ON)=인 보안 문제 local_infile(ON) = ON입니다.

( Com_rollback / (Com_commit + Com_rollback) ) = 149,370 / (1 + 149370) = 100.0%: 비율 은 비용이 듭니다; 앱 로직을 합니다. : - 이비많듭다니이변백경.

( (Com_insert + Com_update + Com_delete + Com_replace) / Com_commit ) = (2879857 + 51107135 + 14596 + 0) / 1 = 5.4e+7커밋당 문 수(모든 InnoDB로 가정) -- 낮음: 트랜잭션에서 쿼리를 그룹화하는 데 도움이 될 수 있음; 높음: 긴 트랜잭션은 다양한 것을 변형시킵니다.

( binlog_format ) = binlog_format = MIXED -- 는 5문/행/혼합으로 됩니다. -- 행을 5.7(10.3)보다선다.

( Max_used_connections ) = 1,075연결에 대한 상한 표시 - 비활성 연결의 수가 많으므로 100개 이상의 활성 연결이 문제가 될 수 있습니다.는 1075을 구분하지 않습니다;Max_used_connections(1075)는 이들을 구분합니다.Threads_running(현재 7)은 즉시 실행됩니다.

( Max_used_connections / host_cache_size ) = 1,075 / 703 = 152.9% 703host_cache_size( 703) 증가

( max_connect_errors ) = 100,000해커들에 대한 작은 보호. -- 아마도 200명을 넘지 않을 것입니다.

( Connections ) = 34,587,635 / 3099872 = 11 /sec연결 -- wait_timeout(현재 28800)을 늘립니다. 풀링을 사용하시겠습니까?

( thread_pool_max_threads ) = 65,536MariaDB의 스레드 풀링에 대한 여러 설정 중 하나 - 값을 낮춥니다.

비정상적으로 작음:

Created_tmp_files = 0.036 /HR
Delete_scan = 0
Handler_read_first = 11 /HR
Table_locks_immediate = 8 /HR
eq_range_index_dive_limit = 0

비정상적으로 큼:

Access_denied_errors = 54,974
Com_show_events = 0.29 /HR
Com_show_master_status = 32 /HR
Com_show_profile = 0.0081 /HR
Com_show_status = 0.23 /sec
Feature_locale = 34 /HR
Handler_discover = 0.06 /HR
Tc_log_page_size = 4,096
Threads_connected = 616
log_slow_rate_limit = 100
max_heap_table_size = 500MB
min(max_heap_table_size, tmp_table_size) = 500MB

비정상 문자열:

Innodb_have_snappy = ON
Slave_heartbeat_period = 0
Slave_received_heartbeats = 0
ft_boolean_syntax = "+ -><()~*:""""&"
lc_messages = fr_FR
log_slow_disabled_statements = admin,sp
log_slow_verbosity = query_plan
old_alter_table = DEFAULT

"교차 사용"은 복합 인덱스의 필요성을 명확하게 나타냅니다.

:OPTIMIZEData_length 증가!; 단지 네, 그수도있요어를 피하는 또입니다. 그건 단지 피해야만 하는 또 다른 이유일 뿐입니다.OPTIMIZE.

쿼리 1

이 작업은 초당 5회 실행되므로 일부 호출을 피할 수 있습니다.

SELECT  MAX(`id`) AS `id`
    FROM  my_domain_enseignant.passations
    WHERE  `id_eleve` IN ('499613','499611','499612','499614',
                '499615','499616','499617','499618','499619','499620',
                '499621','499622','499623','499624','499625','499626',
                '499627','499628','499629','499630','499631','499632',
                '499633','499634'
                         )
      AND  `id_module` = '1'
      AND  `type_seance` = 'normale'
      AND  `type_question` = 'principale'
      AND  `methode` = 'entrainement'
      AND  `premier` = 1\G

제십시오를 제공해 .SHOW CREATE TABLE passations저는 그 테이블에 어떤 인덱스가 있는지 보고 싶습니다.최적은 8열, 복합 및 피복 지수입니다.하지만, 저는 그렇게 많은 열을 피하는 경향이 있습니다. 또한, 해주오시를 제공해 바랍니다.EXPLAIN SELECT인덱스 병합이 "인덱스 병합"으로 표시되면 전체 6개 열이 아니더라도 복합 인덱스가 있는 것이 좋습니다.

쿼리 2

1초에 7번.

SELECT  ge.`id_eleve` as `id`, ea.`last_activity`,
        COUNT(DISTINCT et.id) AS nb_messages,
        DATE_FORMAT(ea.connexion, "%d/%m/%Y à %H:%i") AS connexion,
        AES_DECRYPT(e.nom, 'key') as nom,
        AES_DECRYPT(e.prenom, 'key') as prenom
    FROM  `groupes_eleves` AS ge
    JOIN  `eleves` AS e  ON e.`id` = ge.`id_eleve`
    JOIN  `eleves_activity` AS ea  ON ea.`id_eleve` = ge.`id_eleve`
    LEFT JOIN  `eleves_tchat` AS et
               ON (et.`id_eleve` = ge.`id_eleve`
              AND  `auteur` = "eleve"
              AND  `lu` = "false")
    WHERE  ge.`id_groupe` IN ('44100','44194')
    GROUP BY  ge.`id_eleve`\G 

다음 복합 및 피복 인덱스를 사용하는 경우:

groupes_eleves:   INDEX(id_groupe, id_eleve)
eleves_activity:  INDEX(id_eleve,  last_activity, connexion)
eleves_tchat:     INDEX(id_eleve,  id)  -- you have this (see Note)

복합 인덱스를 추가할 때 선행 열이 동일한 Drop 인덱스.즉, INDEX(a)와 INDEX(a,b)가 모두 있는 경우 전자를 던집니다.

참고: InnoDB에서 보조 키는 암시적으로 끝에 PK의 복사본을 가지고 있습니다.이런 이유로,INDEX(x)그리고.INDEX(x,id)동등합니다.

쿼리 3

UPDATE `my_domain_enseignant`.`eleves_activity`
    SET `last_activity` = 1646889907
    WHERE `id_eleve` = '456599'\G

Big Lock time -- 테이블이 InnoDB입니까?MyISAM이라면 큰 문제입니다.

아이즈id_eleve그자리의 PRIMARY KEY그렇지 않다면, 제공해 주십시오.SHOW CREATE TABLE eleves_activity

보통 <1ms, 하지만 최대 37초! InnoDB와 적절한 키가 있다면, 저는 다른 무언가가 때때로 무언가를 차단하고 있다고 말해야 합니다.

은 다은위치설예다입니정의음▁setting다예니입▁this를 설정하는 예입니다.long_query_time = 1(또는 37보다 작은 항목)은 실제로 이 쿼리로 인한 문제를 발견합니다. 이 쿼리는 1ms 미만이어야 합니다.

쿼리 4

쿼리 3과 동일한 증상 및 원인일 수 있습니다.

쿼리 5

SELECT  gc.`id`, gc.`description`, u.`prenom`, u.`nom`, g.`id` as `id_groupe`
    FROM  `groupes_calibrations` AS gc
    JOIN  `groupes` AS g  ON g.`id` = gc.`id_groupe`
    JOIN  `users` AS u  ON u.`id` = g.`id_enseignant`
    WHERE  gc.`id_groupe` IN ('48587')
      AND  gc.`statut` = 'ouvert'\G

"Rows_examined"가 매우 낮았기 때문에, 저는 당신이 지금 적절한 색인을 가지고 있다고 생각합니다.그렇지 않으면 다음을 권장합니다.

gc:  INDEX(statut, id_groupe, description) -- if description not TEXT
gc:  INDEX(statut, id_groupe) -- if description is TEXT

포스트로그

위의 일부를 수정한 다음 저속 로그를 다시 실행합니다.목록의 맨 위까지 어떤 버블이 표시되는지 확인합니다.

원시 저속 로그(사용 가능한 경우)로 돌아가서 37s 업데이트가 종료된 시점과 동시에 종료된 쿼리를 확인합니다.아마도 그 순간에 끝나는 많은 질문들이 있을 것입니다. 그 중 하나가 악당입니다.(참고: 느린 로그의 타임스탬프는 쿼리의 을 나타냅니다.)

언급URL : https://stackoverflow.com/questions/71348913/random-peaks-in-mysql-load-slowing-all-users