kb.erickguedes.com
MySQL: Administração e Performance

Performance Tuning MySQL

Aula 4 de 6

Configuração de Memória

# /etc/mysql/mysql.conf.d/performance.cnf
[mysqld]
# Buffer pool (InnoDB) — >70% da RAM disponível para DB dedicado
innodb_buffer_pool_size = 8G          # 70-80% RAM total
innodb_buffer_pool_instances = 4      # 1 instância a cada ~2GB

# Log buffer
innodb_log_file_size = 1G             # Total transactions que pode recovery
innodb_log_buffer_size = 64M

# Temp tables
tmp_table_size = 128M
max_heap_table_size = 128M

# Connections
max_connections = 500
thread_cache_size = 32

Query Cache (MySQL < 8.0)

# MySQL 5.7 — query cache (removido no 8.0)
query_cache_type = 1
query_cache_size = 256M

MySQL 8.0: query cache removido

No MySQL 8.0, o query cache foi removido por problemas de escalabilidade.
Alternativas:
├── ProxySQL (caching inteligente)
├── Redis/Memcached (cache externo)
└── Application-level caching

Slow Query Log

-- Configurar
SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 2;       -- queries > 2 segundos
SET GLOBAL log_queries_not_using_indexes = ON;

-- Analisar
mysqldumpslow /var/log/mysql/slow.log

-- pt-query-digest (Percona Toolkit)
pt-query-digest /var/log/mysql/slow.log

-- Exemplo de saída:
-- # Query 1: 0.08QPS, 0.09x concurrency, ID 0xABC
-- # Exec time: 123s total, 2.5s avg
-- # Lock time: 0s total
-- # Rows sent: 100 avg, 10000 max

Índices e EXPLAIN

-- ANALYZE TABLE para atualizar estatísticas
ANALYZE TABLE clientes;

-- EXPLAIN: identificar full table scans
EXPLAIN FORMAT=JSON 
SELECT * FROM pedidos WHERE cliente_id = 1\G

-- pt-index-usage (Percona)
pt-index-usage /var/log/mysql/slow.log --user=root --password=xxx

Status e Métricas

-- Cache hit ratio (ideal > 95%)
SELECT 
    (1 - (Innodb_buffer_pool_reads / GREATEST(Innodb_buffer_pool_read_requests, 1))) * 100
    AS buffer_pool_hit_ratio
FROM performance_schema.global_status;

-- Threads conectadas (vs max_connections)
SELECT VARIABLE_VALUE AS max_conn
FROM performance_schema.global_variables
WHERE VARIABLE_NAME = 'max_connections';

-- Locks aguardando
SELECT * FROM performance_schema.data_lock_waits;

-- Tabelas sem índices primários
SELECT t.table_schema, t.table_name, t.engine
FROM information_schema.tables t
LEFT JOIN information_schema.table_constraints c
    ON t.table_schema = c.table_schema 
    AND t.table_name = c.table_name 
    AND c.constraint_type = 'PRIMARY KEY'
WHERE t.table_schema NOT IN ('mysql', 'performance_schema', 'sys')
    AND c.constraint_name IS NULL;

Configuração por Perfil

# OLTP (WEB APP) — muitas transações pequenas
innodb_buffer_pool_size = 70% RAM
innodb_log_file_size = 1G
innodb_flush_log_at_trx_commit = 1   # segurança máxima
innodb_io_capacity = 1000

# OLAP / Analytics — queries pesadas
innodb_buffer_pool_size = 80% RAM
innodb_log_file_size = 4G
innodb_flush_log_at_trx_commit = 2   # performance
innodb_io_capacity = 2000
tmp_table_size = 256M
max_heap_table_size = 512M

# Batch / Big Data — alta throughput
innodb_buffer_pool_size = 60% RAM
innodb_log_file_size = 8G
innodb_flush_log_at_trx_commit = 2
innodb_flush_method = O_DIRECT

Buffer pool é o parâmetro mais importante — aloque 70-80% da RAM. Slow query log é essencial para identificar gargalos. pt-query-digest do Percona Toolkit analisa queries lentas. Evite query cache no MySQL 8.