mysql資料庫SQL最佳化
1.瞭解sql的執行頻率
show global status like 'Com_%';
show global status like 'Innodb_%';
show global status like 'Connections';
show global status like 'Uptime';
show global status like 'Slow_queries';
2.定位低效的sql語句
慢查詢
show processlist;
3.透過explain分析低效sql執行計劃
mysql索引中包含null,oracle索引不包含null
(1)select_type:
simple:簡單表,不使用表連線或者子查詢
primary:主查詢,即外層的查詢
union:union連線中的第二個或者後面的查詢語句
subquery:子查詢中的第一個select
type:
all:
index:索引全掃描
range:索引範圍掃描
ref:非唯一索引等值查詢
eq_ref:唯一索引等值查詢
extra:
using index :透過索引就能拿到資料
using where:表示最佳化器需要透過索引返回表查詢資料
using filesort: 做了排序操作,(透過索引排序不算在內)
測試樣例wget /> mysql資料版本
+---------------+--------+
| Variable_name | Value |
+---------------+--------+
| version | 5.1.73 |
+---------------+--------+
explain select * from film where rating>9;
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | film | ALL | NULL | NULL | NULL | NULL | 949 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
explain select title from film ;
+----+-------------+-------+-------+---------------+-----------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+-----------+---------+------+------+-------------+
| 1 | SIMPLE | film | index | NULL | idx_title | 767 | NULL | 949 | Using index |
+----+-------------+-------+-------+---------------+-----------+---------+------+------+-------------+
explain select * from payment where customer_id>=300 and customer_id<=350;
+----+-------------+---------+-------+--------------------+--------------------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+--------------------+--------------------+---------+------+------+-------------+
| 1 | SIMPLE | payment | range | idx_fk_customer_id | idx_fk_customer_id | 2 | NULL | 1349 | Using where |
+----+-------------+---------+-------+--------------------+--------------------+---------+------+------+-------------+
explain select * from payment where customer_id=350;
+----+-------------+---------+------+--------------------+--------------------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------+--------------------+--------------------+---------+-------+------+-------+
| 1 | SIMPLE | payment | ref | idx_fk_customer_id | idx_fk_customer_id | 2 | const | 23 | |
+----+-------------+---------+------+--------------------+--------------------+---------+-------+------+-------+
explain select * from film a,film_text b where a.film_id=b.film_id;
+----+-------------+-------+--------+---------------+---------+---------+------------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+---------------+---------+---------+------------------+------+-------------+
| 1 | SIMPLE | a | ALL | PRIMARY | NULL | NULL | NULL | 949 | |
| 1 | SIMPLE | b | eq_ref | PRIMARY | PRIMARY | 2 | sakila.a.film_id | 1 | Using where |
+----+-------------+-------+--------+---------------+---------+---------+------------------+------+-------------+
explain select * from (select * from customer where email='AARON.SELBY@sakilacustomer.org') a;
+----+-------------+------------+--------+---------------+----------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+--------+---------------+----------+---------+------+------+-------+
| 1 | PRIMARY | <derived2> | system | NULL | NULL | NULL | NULL | 1 | |
| 2 | DERIVED | customer | const | uk_email | uk_email | 153 | | 1 | |
+----+-------------+------------+--------+---------------+----------+---------+------+------+-------+
type:(還有一些其他值)
ref_or_null:與ref類似,區別在於條件中包含對null的查詢
index_merge:索引合併最佳化
unique_subquery:in後面是一個查詢主鍵欄位的子查詢
index_subquery:in後面是查詢非唯一索引欄位的子查詢
(2).explain extended詳解
explain select sum(amount) from customer c,payment b where 1=1 and c.customer_id=b.customer_id and email='JANE.BENNETT@sakilacustomer.org';
+----+-------------+-------+-------+--------------------+--------------------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+--------------------+--------------------+---------+-------+------+-------------+
| 1 | SIMPLE | c | const | PRIMARY,uk_email | uk_email | 153 | const | 1 | Using index |
| 1 | SIMPLE | b | ref | idx_fk_customer_id | idx_fk_customer_id | 2 | const | 28 | |
+----+-------------+-------+-------+--------------------+--------------------+---------+-------+------+-------------+
explain extended select sum(amount) from customer c,payment b where 1=1 and c.customer_id=b.customer_id and email='JANE.BENNETT@sakilacustomer.org';
+----+-------------+-------+-------+--------------------+--------------------+---------+-------+------+----------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+-------+--------------------+--------------------+---------+-------+------+----------+-------------+
| 1 | SIMPLE | c | const | PRIMARY,uk_email | uk_email | 153 | const | 1 | 100.00 | Using index |
| 1 | SIMPLE | b | ref | idx_fk_customer_id | idx_fk_customer_id | 2 | const | 28 | 100.00 | |
+----+-------------+-------+-------+--------------------+--------------------+---------+-------+------+----------+-------------+
2 rows in set, 1 warning (0.00 sec)
mysql> show warnings\G
*************************** 1. row ***************************
Level: Note
Code: 1003
Message: select sum(`sakila`.`b`.`amount`) AS `sum(amount)` from `sakila`.`customer` `c` join `sakila`.`payment` `b` where ((`sakila`.`b`.`customer_id` = '77') and ('JANE.BENNETT@sakilacustomer.org' = 'JANE.BENNETT@sakilacustomer.org'))
(3)explain partitions 顯示分割槽使用資訊
4.透過show profile分析sql
select @@profiling;
+-------------+
| @@profiling |
+-------------+
| 0 |
+-------------+
set profiling=1;
show profiles;
show profile for query 8;
+--------------------+----------+
| Status | Duration |
+--------------------+----------+
| starting | 0.000062 |
| Opening tables | 0.000044 |
| System lock | 0.000004 |
| Table lock | 0.000007 |
| init | 0.000012 |
| optimizing | 0.000007 |
| statistics | 0.000013 |
| preparing | 0.000007 |
| executing | 0.000004 |
| Sending data | 0.003732 |
| end | 0.000079 |
| query end | 0.000007 |
| freeing items | 0.000025 |
| logging slow query | 0.000003 |
| cleaning up | 0.000002 |
+--------------------+----------+
15 rows in set (0.00 sec)
注:Sending data狀態表示MYSQL執行緒開始訪問資料並把結果返回給客戶端(所以包含io時間);
select state,sum(duration) as total_r,
ROUND(100*SUM(DURATION)/(SELECT SUM(DURATION)
FROM INFORMATION_SCHEMA.PROFILING
WHERE QUERY_ID=@query_id
),2) AS Pct_R,
count(*) as calls,
sum(duration)/count(*) as "r/call"
from information_schema.profiling
where query_id=@query_id
group by state
order by total_r desc;
show profile cpu for query 8;
MySQL5.6可以透過trace分析最佳化器如何選擇執行計劃
set optimizer_trace="enabled=on",END_MARKERS_IN_JSON=on;
set optimizer_trace_max_mem_size=1000000;
select * from table_name;
select * from information_schema.optimizer_trace\G
show global status like 'Com_%';
show global status like 'Innodb_%';
show global status like 'Connections';
show global status like 'Uptime';
show global status like 'Slow_queries';
2.定位低效的sql語句
慢查詢
show processlist;
3.透過explain分析低效sql執行計劃
mysql索引中包含null,oracle索引不包含null
(1)select_type:
simple:簡單表,不使用表連線或者子查詢
primary:主查詢,即外層的查詢
union:union連線中的第二個或者後面的查詢語句
subquery:子查詢中的第一個select
type:
all:
index:索引全掃描
range:索引範圍掃描
ref:非唯一索引等值查詢
eq_ref:唯一索引等值查詢
extra:
using index :透過索引就能拿到資料
using where:表示最佳化器需要透過索引返回表查詢資料
using filesort: 做了排序操作,(透過索引排序不算在內)
測試樣例wget /> mysql資料版本
+---------------+--------+
| Variable_name | Value |
+---------------+--------+
| version | 5.1.73 |
+---------------+--------+
explain select * from film where rating>9;
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | film | ALL | NULL | NULL | NULL | NULL | 949 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
explain select title from film ;
+----+-------------+-------+-------+---------------+-----------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+-----------+---------+------+------+-------------+
| 1 | SIMPLE | film | index | NULL | idx_title | 767 | NULL | 949 | Using index |
+----+-------------+-------+-------+---------------+-----------+---------+------+------+-------------+
explain select * from payment where customer_id>=300 and customer_id<=350;
+----+-------------+---------+-------+--------------------+--------------------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+--------------------+--------------------+---------+------+------+-------------+
| 1 | SIMPLE | payment | range | idx_fk_customer_id | idx_fk_customer_id | 2 | NULL | 1349 | Using where |
+----+-------------+---------+-------+--------------------+--------------------+---------+------+------+-------------+
explain select * from payment where customer_id=350;
+----+-------------+---------+------+--------------------+--------------------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------+--------------------+--------------------+---------+-------+------+-------+
| 1 | SIMPLE | payment | ref | idx_fk_customer_id | idx_fk_customer_id | 2 | const | 23 | |
+----+-------------+---------+------+--------------------+--------------------+---------+-------+------+-------+
explain select * from film a,film_text b where a.film_id=b.film_id;
+----+-------------+-------+--------+---------------+---------+---------+------------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+---------------+---------+---------+------------------+------+-------------+
| 1 | SIMPLE | a | ALL | PRIMARY | NULL | NULL | NULL | 949 | |
| 1 | SIMPLE | b | eq_ref | PRIMARY | PRIMARY | 2 | sakila.a.film_id | 1 | Using where |
+----+-------------+-------+--------+---------------+---------+---------+------------------+------+-------------+
explain select * from (select * from customer where email='AARON.SELBY@sakilacustomer.org') a;
+----+-------------+------------+--------+---------------+----------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+--------+---------------+----------+---------+------+------+-------+
| 1 | PRIMARY | <derived2> | system | NULL | NULL | NULL | NULL | 1 | |
| 2 | DERIVED | customer | const | uk_email | uk_email | 153 | | 1 | |
+----+-------------+------------+--------+---------------+----------+---------+------+------+-------+
type:(還有一些其他值)
ref_or_null:與ref類似,區別在於條件中包含對null的查詢
index_merge:索引合併最佳化
unique_subquery:in後面是一個查詢主鍵欄位的子查詢
index_subquery:in後面是查詢非唯一索引欄位的子查詢
(2).explain extended詳解
explain select sum(amount) from customer c,payment b where 1=1 and c.customer_id=b.customer_id and email='JANE.BENNETT@sakilacustomer.org';
+----+-------------+-------+-------+--------------------+--------------------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+--------------------+--------------------+---------+-------+------+-------------+
| 1 | SIMPLE | c | const | PRIMARY,uk_email | uk_email | 153 | const | 1 | Using index |
| 1 | SIMPLE | b | ref | idx_fk_customer_id | idx_fk_customer_id | 2 | const | 28 | |
+----+-------------+-------+-------+--------------------+--------------------+---------+-------+------+-------------+
explain extended select sum(amount) from customer c,payment b where 1=1 and c.customer_id=b.customer_id and email='JANE.BENNETT@sakilacustomer.org';
+----+-------------+-------+-------+--------------------+--------------------+---------+-------+------+----------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+-------+--------------------+--------------------+---------+-------+------+----------+-------------+
| 1 | SIMPLE | c | const | PRIMARY,uk_email | uk_email | 153 | const | 1 | 100.00 | Using index |
| 1 | SIMPLE | b | ref | idx_fk_customer_id | idx_fk_customer_id | 2 | const | 28 | 100.00 | |
+----+-------------+-------+-------+--------------------+--------------------+---------+-------+------+----------+-------------+
2 rows in set, 1 warning (0.00 sec)
mysql> show warnings\G
*************************** 1. row ***************************
Level: Note
Code: 1003
Message: select sum(`sakila`.`b`.`amount`) AS `sum(amount)` from `sakila`.`customer` `c` join `sakila`.`payment` `b` where ((`sakila`.`b`.`customer_id` = '77') and ('JANE.BENNETT@sakilacustomer.org' = 'JANE.BENNETT@sakilacustomer.org'))
(3)explain partitions 顯示分割槽使用資訊
4.透過show profile分析sql
select @@profiling;
+-------------+
| @@profiling |
+-------------+
| 0 |
+-------------+
set profiling=1;
show profiles;
show profile for query 8;
+--------------------+----------+
| Status | Duration |
+--------------------+----------+
| starting | 0.000062 |
| Opening tables | 0.000044 |
| System lock | 0.000004 |
| Table lock | 0.000007 |
| init | 0.000012 |
| optimizing | 0.000007 |
| statistics | 0.000013 |
| preparing | 0.000007 |
| executing | 0.000004 |
| Sending data | 0.003732 |
| end | 0.000079 |
| query end | 0.000007 |
| freeing items | 0.000025 |
| logging slow query | 0.000003 |
| cleaning up | 0.000002 |
+--------------------+----------+
15 rows in set (0.00 sec)
注:Sending data狀態表示MYSQL執行緒開始訪問資料並把結果返回給客戶端(所以包含io時間);
select state,sum(duration) as total_r,
ROUND(100*SUM(DURATION)/(SELECT SUM(DURATION)
FROM INFORMATION_SCHEMA.PROFILING
WHERE QUERY_ID=@query_id
),2) AS Pct_R,
count(*) as calls,
sum(duration)/count(*) as "r/call"
from information_schema.profiling
where query_id=@query_id
group by state
order by total_r desc;
show profile cpu for query 8;
MySQL5.6可以透過trace分析最佳化器如何選擇執行計劃
set optimizer_trace="enabled=on",END_MARKERS_IN_JSON=on;
set optimizer_trace_max_mem_size=1000000;
select * from table_name;
select * from information_schema.optimizer_trace\G
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29620572/viewspace-1808099/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- mysql資料庫SQL最佳化2MySql資料庫
- mysql資料庫SQL最佳化3MySql資料庫
- 【MySQL】資料庫最佳化MySql資料庫
- mysql資料庫最佳化MySql資料庫
- MySQL資料庫效能最佳化MySql資料庫
- mysql資料庫最佳化彙總MySql資料庫
- 資料庫最佳化技巧 - SQL語句最佳化資料庫SQL
- MYSQL資料庫------SQL優化MySql資料庫優化
- PG資料庫SQL最佳化小技巧資料庫SQL
- 【資料庫學習】資料庫平臺:mysql,sql server資料庫MySqlServer
- 在SQL Server資料庫中匯入MySQL資料庫Server資料庫MySql
- MySQL 資料庫與 SQL 優化MySql資料庫優化
- SQL Server 資料庫 最佳化 效能瓶頸SQLServer資料庫
- MySQL資料庫高併發最佳化配置MySql資料庫
- 資料庫查詢和資料庫(MySQL)索引的最佳化建議資料庫MySql索引
- Mysql資料庫大表最佳化方案和Mysql大表最佳化步驟MySql資料庫
- 1.4 資料庫和常用SQL語句(正文)——MySQL資料庫命令和SQL語句資料庫MySql
- mysql資料庫最佳化需要遵守的原則MySql資料庫
- MySQL/Oracle資料庫最佳化總結(非常全面)MySqlOracle資料庫
- MySQL資料庫最佳化實踐--硬體方面MySql資料庫
- 分散式 SQL 資料庫與表格最佳化技術分散式SQL資料庫
- 50種方法最佳化SQL Server資料庫查詢SQLServer資料庫
- sql最佳化(mysql)MySql
- 用SQL命令檢視Mysql資料庫大小MySql資料庫
- SQL、Mysql、資料庫到底什麼關係MySql資料庫
- oracle資料庫巡檢最佳化-使用sql語句快速定位資料庫瓶頸Oracle資料庫SQL
- MySQL 資料庫最佳化的具體方法說明MySql資料庫
- MySql資料庫最佳化的幾條核心建議MySql資料庫
- 從運維角度淺談MySQL資料庫最佳化運維MySql資料庫
- 談談資料從sql server資料庫匯入mysql資料庫的體驗(轉)Server資料庫MySql
- mysql資料庫sql語句基礎知識MySql資料庫
- MySQL資料庫:7、SQL常用查詢語句MySql資料庫
- SQL資料庫管理工具:SQLPro for MySQL for Mac資料庫MySqlMac
- MySQL資料庫中SQL語句分幾類?MySql資料庫
- SQL資料庫SQL資料庫
- 【資料庫】mysql資料庫索引資料庫MySql索引
- Mysql資料庫使用Navicat Mysql匯入sql檔案報錯MySql資料庫
- 解析MySQL資料庫效能最佳化的六大技巧MySql資料庫