SlideShare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our User Agreement and Privacy Policy.
SlideShare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our Privacy Policy and User Agreement for details.
Successfully reported this slideshow.
Activate your 14 day free trial to unlock unlimited reading.
Slides da palestra realizada no Dia da Liberdade do Software 2016. Esta palestra mostra algumas maneiras de se obter mais performance com o banco de dados MySQL.
Slides da palestra realizada no Dia da Liberdade do Software 2016. Esta palestra mostra algumas maneiras de se obter mais performance com o banco de dados MySQL.
2.
Marcelo Altmann
Técnologo em Sistemas para Internet
MySQL DBA @ IEDR
Blogueiro - blog.marceloaltmann.com
Oracle ACE Associate - MySQL
Oracle Certified Professional , MySQL 5.6 Database Administrator
Oracle Certified Professional , MySQL 5 Database Administrator
11.
Configuração - Innodb Buffer Pool
● Monitorar: SHOW GLOBAL STATUS LIKE ‘Innodb_buffer_pool_read%’ :
○ Innodb_buffer_pool_reads - Leituras feitas direto no disco
○ Innodb_buffer_pool_read_requests - Leituras feitas na memória
● Innodb_buffer_pool_size (Padrão: 128M)
● Innodb_buffer_pool_dump_at_shutdown
● innodb_buffer_pool_load_at_startup
31.
Índices - Full table scan
CREATE TABLE `city` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`Name` char(35) NOT NULL DEFAULT '',
`CountryCode` char(3) NOT NULL DEFAULT '',
`District` char(20) NOT NULL DEFAULT '',
`Population` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=4080 DEFAULT CHARSET=latin1;
32.
Índices - Full table scan
mysql> EXPLAIN SELECT Name, Population FROM city WHERE CountryCode='BRA' AND Population > 1000000G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: city
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 4188
Extra: Using where
1 row in set (0.00 sec)
33.
Índices - Full table scan
mysql> EXPLAIN SELECT Name, Population FROM city WHERE CountryCode='BRA' AND Population > 1000000G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: city
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 4188
Extra: Using where
1 row in set (0.00 sec)
34.
Índices - Left most part
ALTER TABLE city ADD KEY leftMost(CountryCode, Population, District);
mysql> EXPLAIN SELECT Name, Population FROM city WHERE CountryCode='BRA' AND
Population > 1000000G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: city
type: range
possible_keys: leftMost
key: leftMost
key_len: 7
ref: NULL
rows: 13
Extra: Using index condition
1 row in set (0.00 sec)
35.
Índices - Left most part
ALTER TABLE city ADD KEY leftMost(CountryCode, Population, District);
mysql> EXPLAIN SELECT Name, Population FROM city WHERE CountryCode='BRA' AND
Population > 1000000G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: city
type: range
possible_keys: leftMost
key: leftMost
key_len: 7
ref: NULL
rows: 13
Extra: Using index condition
1 row in set (0.00 sec)
36.
Índices - Left most part
mysql> EXPLAIN FORMAT=JSON SELECT Name, Population FROM city WHERE CountryCode='BRA' AND Population > 1000000;
{
"query_block": {
"select_id": 1,
"table": {
"table_name": "city",
"access_type": "range",
"possible_keys": [
"CountryCode"
],
"key": "CountryCode",
"used_key_parts": [
"CountryCode",
"Population"
],
"key_length": "7",
"rows": 13,
"filtered": 100,
"index_condition": "((`world`.`city`.`CountryCode` = 'BRA') and (`world`.`city`.`Population` > 1000000))"
}
}
}
37.
Índices - Covered index
ALTER TABLE city ADD KEY covered (CountryCode, Population, Name);
mysql> EXPLAIN SELECT Name, Population FROM city WHERE CountryCode='BRA' AND
Population > 1000000G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: city
type: range
possible_keys: covered
key: covered
key_len: 7
ref: NULL
rows: 13
Extra: Using where; Using index
1 row in set (0.00 sec)
38.
Índices - Covered index
ALTER TABLE city ADD KEY covered (CountryCode, Population, Name);
mysql> EXPLAIN SELECT Name, Population FROM city WHERE CountryCode='BRA' AND
Population > 1000000G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: city
type: range
possible_keys: covered
key: covered
key_len: 7
ref: NULL
rows: 13
Extra: Using where; Using index
1 row in set (0.00 sec)
40.
Tabelas temporárias
● GROUP BY
● UNION
● SUBQUERY + WHERE
● Memória: Memory Engine
● Disco:
○ 5.6 - MyIsam Engine
○ 5.7 - Innodb Engine
● Memory Engine:
○ Não tem suporte a campos BLOB / TEXT
● https://dev.mysql.com/doc/refman/5.6/en/internal-temporary-tables.html
41.
Tabelas temporárias
● tmp_table_size - tamanho máximo de uma tabela temporária
● max_head_table_size - tamanho máximo de uma tabela que utiliza memory engine
● Tamanho tabela temporária:
○ Maior que tmp_table_size ou max_head_table_size = criada em disco
● Monitorar:
mysql> SHOW GLOBAL STATUS LIKE 'Created_tmp%tables';
+-------------------------+-------+
| Variable_name | Value |
+-------------------------+-------+
| Created_tmp_disk_tables | 3 |
| Created_tmp_tables | 17 |
+-------------------------+-------+
43.
Identificação de queries
● SHOW [FULL] PROCESSLIST
● Slow query log
● performance_schema.events_statements_summary_by_digest
44.
Identificação de queries - Processlist
● Mostra as conexões atuais e seus status
mysql> show processlist;
+----+------+-----------+-----------+---------+------+----------------+-----------------------------------------------------------------------------------------
---------+
| Id | User | Host | db | Command | Time | State | Info
|
+----+------+-----------+-----------+---------+------+----------------+-----------------------------------------------------------------------------------------
---------+
| 8 | root | localhost | employees | Query | 4 | Writing to net | SELECT MAX(salary) FROM salaries JOIN employees USING (emp_no) WHERE gender = 'M' GROUP
BY emp_no |
| 9 | root | localhost | employees | Query | 0 | init | show processlist
|
+----+------+-----------+-----------+---------+------+----------------+-----------------------------------------------------------------------------------------
---------+
2 rows in set (0.00 sec)
45.
Identificação de queries - Slow Query
● Slow_query_log
● Long_query_time = N
46.
Identificação de queries - Slow Query
# Time: 160908 17:38:01
# User@Host: root[root] @ localhost [] Id: 2
# Query_time: 1.127100 Lock_time: 0.000852 Rows_sent: 1000 Rows_examined: 297918
use employees;
SET timestamp=1473370681;
SELECT d.dept_name AS 'Dept', CONCAT(em.last_name, ' ', em.first_name) AS 'Manager last, first', CONCAT(e.last_name,' ',
e.first_name, ' ', t.title) AS 'Employee last, first (title)' FROM dept_manager AS dm LEFT JOIN dept_emp AS de ON de.dept_no
= dm.dept_no LEFT JOIN departments AS d ON d.dept_no = dm.dept_no LEFT JOIN employees AS e ON e.emp_no = de.emp_no LEFT JOIN
employees AS em ON em.emp_no = dm.emp_no LEFT JOIN titles AS t ON t.emp_no = e.emp_no WHERE dm.emp_no = e.emp_no AND
dept_name = 'Sales' OR dept_name = 'Marketing' AND dm.to_date >= '2012-05-07' AND t.to_date > '2012-05-07' AND de.to_date >
'2012-05-07' ORDER BY e.last_name, e.first_name limit 1000;
# Time: 160908 17:38:27
# User@Host: root[root] @ localhost [] Id: 2
# Query_time: 4.236115 Lock_time: 0.000377 Rows_sent: 179973 Rows_examined: 2366291
SET timestamp=1473370707;
SELECT MAX(salary) FROM salaries JOIN employees USING(emp_no) WHERE gender = 'M' GROUP BY emp_no;
# Time: 160908 17:38:33
# User@Host: root[root] @ localhost [] Id: 2
# Query_time: 3.268998 Lock_time: 0.000349 Rows_sent: 179973 Rows_examined: 2366291
SET timestamp=1473370713;
SELECT MAX(salary) FROM salaries JOIN employees USING(emp_no) WHERE gender = 'M' GROUP BY emp_no;
47.
Identificação de queries - performance schema
● Ativado por padrão desde a versão 5.6.6
● DIGEST:
○ SELECT Name, Population FROM city WHERE CountryCode='BRA' AND Population > 1000000;
○ SELECT Name, Population FROM city WHERE CountryCode='USA' AND Population > 5000000;
○ SELECT Name , Population FROM city WHERE CountryCode = ? AND Population > ?;
● Possibilita identificar queries :
○ Não utilizam index:
SELECT DIGEST_TEXT FROM events_statements_summary_by_digest WHERE SUM_NO_INDEX_USED > 0;
○ Usam tabelas temporárias no disco:
SELECT DIGEST_TEXT FROM events_statements_summary_by_digest WHERE SUM_CREATED_TMP_DISK_TABLES > 0;