2014/01/17

mysql SlowLog  見方 slow sql 分析


# Time: 040624  1:25:24 
# User@Host: [ODBC] @ localhost [127.0.0.1]
# Query_time: 5  Lock_time: 0  Rows_sent: 30670  Rows_examined: 38828
select * from city 、country 、language where country.code=city.country
 and city.country=language.country;
1行目 記録日時
 2行目 ユーザーIDとリクエストした端末
 3行目 Query_time(実行時間) Lock_time(ロック時間) Rows_sent(送信行数) Rows_examined(処理対象となった行数)
 4行目 SQL文

・queries that do not use indexes for lookups are not logged
 if you want log_queries_not_using_indexes,
・change log file :  Set slow_query_log_file 


mysql explain
mysql> explain select * from city \G;
*************************** 1. row ***************************
        table: city               対象テーブル名
         type: ALL                テーブル内のすべてのレコードを処理対処とする
possible_keys: NULL               使用可能なインデックスを表す
          key: NULL               実際に使用したインデックスを表す
      key_len: NULL               実際に使用したインデックス長を表す
          ref: NULL               行の特定方法を表す
         rows: 4079               結果として返したレコード数を表す
        Extra:                    クエリーに関する追加情報を表す
1 row in set (0.00 sec)
EXPLAINコマンドはどのようにクエリを書き換えればいいかについては何も教えてくれない
そのSQLはどこで時間を掛かった?
ぜんぜんわからない。
 EXPLAIN SELECT でどんな風に検索されているか確認だけかな。。。。。
★TYPE
Const     一意にレコードを選択できる(UNIQUE や PRIMARY KEYを使用)
eq_ref     複数のテーブルごとに一意にレコードを選択できる
ref     インデックスを使用してレコードを選択できる(UNIQUE や PRIMARY KEYではないインデックス)
range     インデックスを使用して範囲に該当するレコードを選択できる
ALL     テーブル内の全てのレコードを検査する



mysql> show table status like 'city' \G;
*************************** 1. row ***************************
           Name: city                    テーブル名
           Type: MyISAM                  テーブル・タイプ
     Row_format: Fixed                   レコードの長さを表す
           Rows: 4079                    格納されている行数
 Avg_row_length: 67                      平均レコード長
    Data_length: 273293                  使用容量
Max_data_length: 287762808831            最大レコード数(最大格納容量)
   Index_length: 83968                   インデックス・ファイル容量
      Data_free: 0                       開放可能な容量
 Auto_increment: 4080                    次に使用する連番
    Create_time: 2004-06-23 22:56:37     テーブル作成日時
    Update_time: 2004-06-23 22:56:38     テーブル更新日時
     Check_time: 2004-06-23 22:56:38     テーブル検査日時
 Create_options:                         テーブル作成時のオプション
        Comment:                         コメント
1 row in set (0.00 sec)
ーーーーーーーーーーーーー


・そのSQLはどこで時間を掛かった?
set profiling=1;
 sqlを実行する
 SHOW PROFILE;
 
 mysql> SHOW PROFILE;
+---------------------------+----------+
| Status                    | Duration |
+---------------------------+----------+
| starting                  | 0.000089 |
| Opening tables            | 0.000237 |
| System lock               | 0.000005 |
| Table lock                | 0.000009 |
| init                      | 0.000009 |
| optimizing                | 0.000005 |
| statistics                | 0.000009 |
| preparing                 | 0.000009 |
| executing                 | 0.001803 |
| converting HEAP to MyISAM | 0.003110 |
| executing                 | 0.982382 |
| Sending data              | 0.031821 |
| end                       | 0.000017 |
| query end                 | 0.000006 |
| freeing items             | 0.000080 |
| removing tmp table        | 0.020215 |
| closing tables            | 0.000021 |
| logging slow query        | 0.000007 |
| cleaning up               | 0.000009 |
+---------------------------+----------+
19 rows in set (0.00 sec)

 SHOW PROFILEは、デフォルトではStatusとDurationを表示する。StatusはSHOW PROCESSLISTで表示されるステータスと同じだ。Durationは経過時間である。つまり、どの段階の処理にどのぐらい時間がかかったのかが一目で分かるのである
 
オプション: 
    ALL・・・すべての情報を表示。
    BLOCK IO・・・ディスクへのBlock I/Oの回数。
    CONTEXT SWITCHES・・・コンテキストスイッチの回数。
    CPU・・・CPUの使用時間。(システム、ユーザの内訳など。)
    IPC・・・メッセージ送受信。
    MEMORY・・・未実装。(これは待望の機能である!!)
    PAGE FAULTS・・・ページフォルト回数。
    SWAPS・・・スワップアウトの回数。


ysql> SHOW PROFILES;
+----------+------------+-------------------------------+
| Query_ID | Duration   | Query                         |
+----------+------------+-------------------------------+
|        1 | 1.03984300 | SHOW LOCAL STATUS             |
|        2 | 0.69961500 | SHOW GLOBAL STATUS            |
|        3 | 0.00078000 | SHOW DATABASES                |
|        4 | 0.00022000 | SELECT DATABASE()             |
|        5 | 0.00059500 | show databases                |
|        6 | 0.54332000 | show tables                   |
|        7 | 0.00092800 | SHOW TABLES                   |
|        8 | 0.00031400 | SELECT * FROM ptest LIMIT 100 |
+----------+------------+-------------------------------+
8 rows in set (0.00 sec)

特定のクエリの情報を見たい場合には次のコマンドを実行する。
profiling_history_sizeのデフォルト値は15、最大値は100

1
mysql> SHOW PROFILE SOURCE FOR QUERY 1;

select count(userinfovi0_.user_id) as col_0_0_ from userinfo_view userinfovi0_ limit 2;
ーーーー>
*************************** 11. row ***************************
             Status: Sending data
           Duration: 0.670087       Sending dataは一番時間掛かった。
           CPU_user: 2.424631
         CPU_system: 0.378942
  Context_voluntary: 9806
Context_involuntary: 182
       Block_ops_in: 0
      Block_ops_out: 4168
      Messages_sent: 0
  Messages_received: 0
  Page_faults_major: 0
  Page_faults_minor: 8
              Swaps: 0
    Source_function: exec
        Source_file: sql_executor.cc
        Source_line: 187
ーーーーーーー>       
Sending dataは、読み込みと絞りこみに掛かってる時間       
This is quite a misleading status. It should be called "reading and filtering data".
This means that MySQL has some data stored on the disk (or in memory) which is yet to be read and sent over. It may be the table itself, an index, a temporary table, a sorted output etc
この辺でMySQLのファイルが上手くキャッシュメモリに乗っていないのではないか? という疑惑が
MySQLのtable_cacheは、テーブルそのもののキャッシュではなく、テーブルに必要なファイルのハンドラをキャッシュする領域
テーブルそのもののキャッシュと勘違い

Page_faults_major: 0ーー>メモリー上はない、コスト高い
Page_faults_minor: 8ーー>メモリー上はある。登録されいていない。

数据跨页,IO 大,explain显示下查询计划,还有表结构     
ページフォールト (page fault) とは、プログラムが物理メモリがマップされていない仮想アドレス空間上のページにアクセスしたときにハードウェアが発生する割り込み(または例外)である
ーーー>DISKに取りに行くのこと