Reprinted from http://www.cnblogs.com/duanxz/archive/2013/01/23/2872537.html
Analysis and diagnosis tool three: use show profiles to analyze SQL performance
Analyzing the overhead caused by SQL execution is an important means of optimizing SQL. In MySQL databases, SQL profiling can be enabled by configuring the profiling parameter. This parameter can be set at the global and session level. For the global level, it affects the entire MySQL instance, while the session level tightly affects the current session. After this parameter is enabled, subsequent SQL statements will record their resource overhead, such as IO, context switching, CPU, Memory , and so on. According to these costs, the current SQL bottleneck is further analyzed for optimization and adjustment. This article describes how to use the MySQL profile and does not involve specific sample analysis.
How to check the time-consuming steps of executing SQL: open the profile, send sql, check the resource cost result of the profile, and close the profile.
Use show profiles to analyze sql performance.
Show profiles were added after 5.0.37 . To use this feature, make sure the version is after 5.0.37.
View database version
mysql> select version();
profile is disabled by default
mysql> show profiles;
Empty set (0.02 sec)
Verify the modified result
mysql> show variables like "%pro%";
you can see that profiling is OFF by default.
Open the profile and test
Open profile
mysql> set profiling=1;
Get help with profiles
help profile;
root@localhost[sakila]> help profile; Name: 'SHOW PROFILE' Description: Syntax: SHOW PROFILE [type [, type] ... ] [FOR QUERY n] [LIMIT row_count [OFFSET offset]] type: ALL -- Display all overhead information | BLOCK IO -- Display block IO related overhead | CONTEXT SWITCHES -- Context switch related overhead | CPU -- Display CPU related overhead information | IPC -- Display send and receive related overhead information | MEMORY - -Display memory related overhead information | PAGE FAULTS --Display page fault related overhead information | SOURCE --Display and Source_function, Source_file, Source_line related overhead information | SWAPS --Display swap times related overhead information The SHOW PROFILE and SHOW PROFILES statements display profiling information that indicates resource usage for statements executed during the course of the current session. *Note*: These statements are deprecated as of MySQL 5.6.7 and will be removed in a future MySQL release. Use the Performance Schema instead; see http: // dev.mysql.com/doc/refman/5.6/en/performance-schema.html . -- The above description will be removed from 5.6.7 onwards and replaced with Performance Schema instead -- in In the Oracle database, autotrace is used to analyze a single SQL and obtain the real execution plan and its cost information
Execute business SQL and analyze the example with profile:
-- Post SQL query root @localhost [ sakila ] > select count ( * ) from customer; + -- --------+ | count ( * ) | + -- --------+ | 599 | + -- --------+ --View all generated profiles for the current session root @localhost [ sakila ] > show profiles; + -- --------+------------+----- ---------------------------+ | Query_ID | Duration | Query | + -- --------+--- ---------+--------------------------------+ | 1 | 0.00253600 | show variables like ' %profil% ' | | 2 | 0.00138150 | select count (*) from customer | +----------+------------+--------------------------------+ 2 rows in set, 1 warning (0.01 sec) -- We see 2 warnings, one before, now one root @localhost [ sakila ] > show warnings; -- The result below indicates that SHOW PROFILES will be replaced by Performance Schema in the future + -- ------- +------+------------------------------------------------------ -------------------------------------------------- ------------------+ | Level | Code | Message | + -- -------+------+------ -------------------------------------------------- -------------------------------------------------- ----+ | Warning| 1287 | 'SHOW PROFILES' is deprecated and will be removed in a future release. Please use Performance Schema instead | +---------+------+--------------------------------------------------------------------------------------------------------------+
Get the cost information of the SQL statement
--You can directly use show profile to view the cost information of the previous SQL statement --Note, statements such as show profile will not be profiled, that is, they will not generate Profiling themselves --Our show profile below looks at the corresponding overhead generated by show warnings root@localhost[sakila]> show profile; +----------------+----------+ | Status | Duration | +----------------+----------+ | starting | 0.000141 | | query end | 0.000058 | | closing tables | 0.000014 | | freeing items | 0.001802 | | cleaning up | 0.000272 | +----------------+----------+ --as the following query show warnings is added to profiles root@localhost[sakila]> show profiles; +----------+------------+--------------------------------+ | Query_ID | Duration | Query | +----------+------------+--------------------------------+ | 1 | 0.00253600 | show variables like '%profil%' | | 2 | 0.00138150 | select count(*) from customer | | 3 | 0.00228600 | show warnings | +----------+------------+--------------------------------+ --Get the cost of the specified query (the cost details of the second query) root@localhost[sakila]> show profile for query 2; +----------------------+----------+ | Status | Duration | +----------------------+----------+ | starting | 0.000148 | | checking permissions | 0.000014 | | Opening tables | 0.000047 | | init | 0.000023 | | System lock | 0.000035 | | optimizing | 0.000012 | | statistics | 0.000019 | | preparing | 0.000014 | | executing | 0.000006 | | Sending data | 0.000990 | | end | 0.000010 | | query end | 0.000011 | | closing tables | 0.000010 | | freeing items | 0.000016 | | cleaning up | 0.000029 | +----------------------+----------+ --View the overhead of a specific part, the following is the overhead of the CPU part root@localhost[sakila]> show profile cpu for query 2 ; +----------------------+----------+----------+------------+ | Status | Duration | CPU_user | CPU_system | +----------------------+----------+----------+------------+ | starting | 0.000148 | 0.000000 | 0.000000 | | checking permissions | 0.000014 | 0.000000 | 0.000000 | | Opening tables | 0.000047 | 0.000000 | 0.000000 | | init | 0.000023 | 0.000000 | 0.000000 | | System lock | 0.000035 | 0.000000 | 0.000000 | | optimizing | 0.000012 | 0.000000 | 0.000000 | | statistics | 0.000019 | 0.000000 | 0.000000 | | preparing | 0.000014 | 0.000000 | 0.000000 | | executing | 0.000006 | 0.000000 | 0.000000 | | Sending data | 0.000990 | 0.001000 | 0.000000 | | end | 0.000010 | 0.000000 | 0.000000 | | query end | 0.000011 | 0.000000 | 0.000000 | | closing tables | 0.000010 | 0.000000 | 0.000000 | | freeing items | 0.000016 | 0.000000 | 0.000000 | | cleaning up | 0.000029 | 0.000000 | 0.000000 | +----------------------+----------+----------+------------+ --The following is the overhead of the MEMORY part root@localhost[sakila]> show profile memory for query 2 ; +----------------------+----------+ | Status | Duration | +----------------------+----------+ | starting | 0.000148 | | checking permissions | 0.000014 | | Opening tables | 0.000047 | | init | 0.000023 | | System lock | 0.000035 | | optimizing | 0.000012 | | statistics | 0.000019 | | preparing | 0.000014 | | executing | 0.000006 | | Sending data | 0.000990 | | end | 0.000010 | | query end | 0.000011 | | closing tables | 0.000010 | | freeing items | 0.000016 | | cleaning up | 0.000029 | +----------------------+----------+ --View different resource costs at the same time root@localhost[sakila]> show profile block io,cpu for query 2; +----------------------+----------+----------+------------+--------------+---------------+ | Status | Duration | CPU_user | CPU_system | Block_ops_in | Block_ops_out | +----------------------+----------+----------+------------+--------------+---------------+ | starting | 0.000148 | 0.000000 | 0.000000 | 0 | 0 | | checking permissions | 0.000014 | 0.000000 | 0.000000 | 0 | 0 | | Opening tables | 0.000047 | 0.000000 | 0.000000 | 0 | 0 | | init | 0.000023 | 0.000000 | 0.000000 | 0 | 0 | | System lock | 0.000035 | 0.000000 | 0.000000 | 0 | 0 | | optimizing | 0.000012 | 0.000000 | 0.000000 | 0 | 0 | | statistics | 0.000019 | 0.000000 | 0.000000 | 0 | 0 | | preparing | 0.000014 | 0.000000 | 0.000000 | 0 | 0 | | executing | 0.000006 | 0.000000 | 0.000000 | 0 | 0 | | Sending data | 0.000990 | 0.001000 | 0.000000 | 0 | 0 | | end | 0.000010 | 0.000000 | 0.000000 | 0 | 0 | | query end | 0.000011 | 0.000000 | 0.000000 | 0 | 0 | | closing tables | 0.000010 | 0.000000 | 0.000000 | 0 | 0 | | freeing items | 0.000016 | 0.000000 | 0.000000 | 0 | 0 | | cleaning up | 0.000029 | 0.000000 | 0.000000 | 0 | 0 | +----------------------+----------+----------+------------+--------------+---------------+ --The following SQL statement is used to query the SQL cost of query_id 2, and it is sorted in reverse order by the maximum consumption time root@localhost[sakila]> set @query_id=2; root@localhost[sakila]> 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; +----------------------+----------+-------+-------+--------------+ | STATE | Total_R | Pct_R | Calls | R/Call | +----------------------+----------+-------+-------+--------------+ | Sending data | 0.000990 | 71.53 | 1 | 0.0009900000 |--The maximum time spent is sending data | starting | 0.000148 | 10.69 | 1 | 0.0001480000 | | Opening tables | 0.000047 | 3.40 | 1 | 0.0000470000 | | System lock | 0.000035 | 2.53 | 1 | 0.0000350000 | | cleaning up | 0.000029 | 2.10 | 1 | 0.0000290000 | | init | 0.000023 | 1.66 | 1 | 0.0000230000 | | statistics | 0.000019 | 1.37 | 1 | 0.0000190000 | | freeing items | 0.000016 | 1.16 | 1 | 0.0000160000 | | preparing | 0.000014 | 1.01 | 1 | 0.0000140000 | | checking permissions | 0.000014 | 1.01 | 1 | 0.0000140000 | | optimizing | 0.000012 | 0.87 | 1 | 0.0000120000 | | query end | 0.000011 | 0.79 | 1 | 0.0000110000 | | end | 0.000010 | 0.72 | 1 | 0.0000100000 | | closing tables | 0.000010 | 0.72 | 1 | 0.0000100000 | | executing | 0.000006 | 0.43 | 1 | 0.0000060000 | +----------------------+----------+-------+-------+--------------+ --After profiling is turned on, we can view it through show profile, etc. The essence is that these overhead information are recorded in the information_schema.profiling table --As in the following query, some information is omitted profiling root@localhost[information_schema]> select * from profiling limit 3,3\G; *************************** 1. row *************************** QUERY_ID: 1 SEQ: 5 STATE: init DURATION: 0.000020 CPU_USER: 0.000000 CPU_SYSTEM: 0.000000 CONTEXT_VOLUNTARY: 0 CONTEXT_INVOLUNTARY: 0 BLOCK_OPS_IN: 0 BLOCK_OPS_OUT: 0 MESSAGES_SENT: 0 MESSAGES_RECEIVED: 0 PAGE_FAULTS_MAJOR: 0 PAGE_FAULTS_MINOR: 0 SWAPS: 0 SOURCE_FUNCTION: mysql_prepare_select SOURCE_FILE: sql_select.cc SOURCE_LINE: 1050 --Stop profile, you can set profiling parameters, or after the session exits, profiling will be automatically closed root@localhost[sakila]> set profiling=off; Query OK, 0 rows affected, 1 warning (0.00 sec)