MySQL 5.1보다 느린 Mariadb 5.5
MySQL 5.1 서버에서는 약 20초 만에 실행되지만 MariaDB 5.5 서버에서는 약 15분이 걸리는 쿼리가 있습니다.key_buffer_size 및 tmp_table_size 및 max_heap_table_size와 같은 일반적인 의심치는 모두 동일합니다(128M).대부분의 설정은 동일(query_cache 등)
쿼리:
SELECT products.id,
concat(publications.company_name,' [',publications.quote,'] ', products.name) as n,
products.impressions,
products.contacts,
is_channel,
sl.i,
count(*)
FROM products
LEFT JOIN publications ON products.publications_id = publications.id
LEFT OUTER JOIN (
SELECT adspace.id AS i,
slots.products_id FROM adspace
LEFT JOIN slots ON adspace.slots_id = slots.id
AND adspace.end > '2016-01-25 10:28:49'
WHERE adspace.active = 1) AS sl
ON sl.products_id = products.id
WHERE 1 = 1
AND publications.active=1
GROUP BY products.id
ORDER BY n ASC;
유일한 차이점은 설명 단계입니다.
오래된 서버(MySQL 5.1)
+----+-------------+--------------+--------+---------------+---------+---------+-----------------------------------------+--------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------------+--------+---------------+---------+---------+-----------------------------------------+--------+---------------------------------+
| 1 | PRIMARY | products | ALL | NULL | NULL | NULL | NULL | 6568 | Using temporary; Using filesort |
| 1 | PRIMARY | publications | eq_ref | PRIMARY | PRIMARY | 4 | db.products.publications_id | 1 | Using where |
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 94478 | |
| 2 | DERIVED | adspace | ALL | NULL | NULL | NULL | NULL | 101454 | Using where |
| 2 | DERIVED | slots | eq_ref | PRIMARY | PRIMARY | 4 | db.adspace.slots_id | 1 | |
+----+-------------+--------------+--------+---------------+---------+---------+-----------------------------------------+--------+---------------------------------+
새 서버(MariaDB 5.5)
+------+-------------+--------------+--------+---------------+---------+---------+-----------------------------------------+--------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+--------------+--------+---------------+---------+---------+-----------------------------------------+--------+---------------------------------+
| 1 | SIMPLE | products | ALL | test_idx | NULL | NULL | NULL | 6557 | Using temporary; Using filesort |
| 1 | SIMPLE | publications | eq_ref | PRIMARY | PRIMARY | 4 | db.products.publications_id | 1 | Using where |
| 1 | SIMPLE | adspace | ALL | NULL | NULL | NULL | NULL | 100938 | Using where |
| 1 | SIMPLE | slots | eq_ref | PRIMARY | PRIMARY | 4 | db.adspace.slots_id | 1 | Using where |
+------+-------------+--------------+--------+---------------+---------+---------+-----------------------------------------+--------+---------------------------------+
작업 속도를 높이기 위해 새 서버의 제품 테이블에 인덱스가 추가되었지만 아무 소용이 없었습니다.
엔진 변수:
이전 서버:
mysql> show variables like '%engine%';
+---------------------------+--------+
| Variable_name | Value |
+---------------------------+--------+
| engine_condition_pushdown | ON |
| storage_engine | MyISAM |
+---------------------------+--------+
mysql> show variables like '%buffer_pool%';
+-------------------------+---------+
| Variable_name | Value |
+-------------------------+---------+
| innodb_buffer_pool_size | 8388608 |
+-------------------------+---------+
새 서버:
MariaDB [db]> show variables like '%engine%';
+---------------------------+--------+
| Variable_name | Value |
+---------------------------+--------+
| default_storage_engine | InnoDB |
| engine_condition_pushdown | OFF |
| storage_engine | InnoDB |
+---------------------------+--------+
MariaDB [db]> show variables like '%buffer_pool%';
+---------------------------------------+-----------+
| Variable_name | Value |
+---------------------------------------+-----------+
| innodb_blocking_buffer_pool_restore | OFF |
| innodb_buffer_pool_instances | 1 |
| innodb_buffer_pool_populate | OFF |
| innodb_buffer_pool_restore_at_startup | 0 |
| innodb_buffer_pool_shm_checksum | ON |
| innodb_buffer_pool_shm_key | 0 |
| innodb_buffer_pool_size | 134217728 |
+---------------------------------------+-----------+
쿼리에 사용되는 모든 테이블은 MyISAM(구 서버와 신 서버 모두)입니다.
프로파일링에 따르면 오래된 쿼리는 'tmp 테이블 복사'에 약 16초, 새로운 서버는 이 페이즈에서 약 800초 소요됩니다.
새 서버에는 모두 스토리지용 SSD 디스크가 있으며 이전 서버에는 일반 디스크가 있습니다.
편집: MySQL 5.5 서버도 가지고 있으며 쿼리는 약 10초밖에 걸리지 않습니다.또한 내가 볼 수 있는 한 모든 설정이 동일하다.
나는 그것을 표로 요약하려고 했다.
Location: Customer Own Customer
MySQL Type: MySQL MySQL MariaDB
Mysql Version: 5.1.56-community-log 5.5.39-1-log (Debian) 5.5.44-MariaDB-log
HDD: Normal Normal SSD
Type: Virtual Real Virtual
Query time: ~15s ~10s ~15min
DB engine: MyISAM InnoDB InnoDB
Table Engine: MyISAM MyISAM MyISAM
쿼리를 다시 쓰고 싶지 않지만(일부 작업이 필요할 수도 있지만) 두 머신의 차이를 찾고 싶습니다.MariaDB에서는 이상적이지 않은 설정이지만 찾을 수 없습니다.
위의 설명에서 파생 테이블 Marge Optimization이 사용되고 있음을 알 수 있습니다.불행히도 당신 경우엔 테이블 전체를 스캔하는 대신adspace
약 6,000개 완료.
가능한 해결책은 쿼리 전에 최적화를 해제하는 것입니다.set optimizer_switch='derived_merge=off';
. 하위 호환성이 있는 다른 방법은 다음을 추가하는 것입니다.GROUP BY adspace.id, slots.products_id
subquery(결과를 변경하지 않는 경우 - 조인된 모든 테이블의 PK를 그룹화하는 것이 가장 안전합니다)로 이행합니다.이 서브쿼리는 다른 시멘틱을 가지기 때문에 머지를 금지합니다.
이에 대해 보고된 옵티마이저 버그가 1개 있습니다.고객님의 경우 도움이 될 수 있습니다.
이것이 정답은 아닐 수 있지만 MariaDB 5.5에서는 다른 알고리즘을 사용하여 조인을 수행합니다.MariaDB 5.5 Batch Key Access Join이 도입된 것으로 알고 있습니다.MySQL 또는 MariaDB의 이전 버전은 다른 버전을 사용합니다.대부분의 경우 새 버전이 더 빠를 수 있지만 특정 테이블은 이전 테이블을 사용하는 것이 더 나을 수 있습니다.
편집: 다른 스토리지 엔진을 사용했다고 말씀하셨기 때문에 이 답변은 생략될 수 있습니다.
언급URL : https://stackoverflow.com/questions/35011477/mariadb-5-5-slower-than-mysql-5-1
'source' 카테고리의 다른 글
JPA와 JDBC는 어떻게 다른가요? (0) | 2023.01.09 |
---|---|
목록을 비우려면 어떻게 해야 하나요? (0) | 2023.01.09 |
Jest: 객체 키와 값을 테스트하는 방법 (0) | 2023.01.09 |
배열에서 쿼리 문자열을 빌드하는 PHP 함수 (0) | 2023.01.09 |
java.net 수정 방법Socket Exception:부러진 파이프? (0) | 2023.01.09 |