2017-01-20 6 views
4

私はこの単純なテーブルMySQLの悪いパフォーマンス

CREATE TABLE `user_did_something` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `something_id` int(11) NOT NULL, 
    `user_id` int(11) NOT NULL, 
    `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    `active` int(1) NOT NULL DEFAULT '1' 
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 

-- Indexes for table `user_did something` 
ALTER TABLE `user_did_something` 
    ADD PRIMARY KEY (`id`); 

を持っていると私は実行のための時間は〜70msである

INSERT INTO user_did_something (something_id, user_id) VALUES (1,11) 

に挿入しようとします。

異なるマシンで同じ構造をテストすると、実行時間は約3msです。

追加情報:

  • バージョン10.0.28-MariaDB-0ubuntu0.16.04

  • テーブルには、行

  • インデックスのみがプライマリであるカラムidするためのものであるありませんでした。

これをデバッグする方法はわかりません。オンラインでいくつかのものを読んで、すべてを再開しましたが、結果は同じです。

私はマシンにmysqlサーバを再インストールする必要なしに、このようなものをデバッグする方法に関するガイダンスを探しています。

+0

あなたの 'CREATE TABLE'はあなたが' PRIMARY KEY(id) 'を持っていると言っていません。 'SHOW CREATE TABLE'をもう一度実行してください。 –

+0

他のクエリが同じテーブルに同時に触れている可能性がありますか?サーバーを再起動した直後の70msで、テーブルがまだ開かれていなかった場合、およびまだキャッシュされていないその他のものがあった場合。 –

+0

@RickJames質問を編集しました。サーバーはテスト用であり、クエリを実行している間は何もテーブルに触れていません。再起動せずに2日後にテストした後、再起動後もテストしました。クエリには約70〜120ミリ秒かかります。ほとんどの場合、約70msかかります。 –

答えて

0

私は前と同じ問題を抱え、MySQLを再起動して問題を解決しました。あなたが言ったように、あなたはそれを前に試しました。私はお勧めします:

あなたのUbuntuをお持ちの場合は、ファイアウォールをチェックしてください。

チェックキャッシュサイズと、それがオンになっているかどうかを確認:

SHOW PROCESSLIST; 

チェッククエリのコストを使用すると、より多くのXの$のstatement_analysisによって:

遅く何のプロセス実行と多分

SHOW VARIABLES LIKE have_query_cache; 
SHOW VARIABLES LIKE query_cache_size; 

チェック

SELECT * FROM sys.`x$statement_analysis` 

グローバルステータスを確認してください。あなたはThreads_connectedのように、そこに非常に有用な情報を見つけることができます。

SHOW GLOBAL STATUS 
2

私は私のマシン上でMySQLサーバを再インストールする必要がなく、このようなものをデバッグする方法についてのガイダンスを探しています。

私はあなたの質問のこの部分に答えようとします。だから、あなたは何らかのプロセスの裏側を見て、それが何をしているのかを見たいと思っています。それを再コンパイル、再インストール、再起動する必要はなく、すぐに出荷されるトレースには制限されたくありません。

これは良い機会ですDTrace!あなたのプロセスが何をしているのかを見ることができます(そしてmuchmore)。

DTraceは、少なくともSolaris、Mac OS X *、FreeBSD、およびI hear a port exists for Linuxで利用できます。それ以外の場合は、別のユーティリティ(BPF tracing got merged into Linux 4.9-rc1 recently)を使用して同様の情報をトレースすることができます。

* Mac OS Xユーザは、関数から入り、戻ってあなたがリアルタイムでmysqldを見ることができ、システムの整合性の保護から

それを除外することによって、explicitly permit DTrace to runにする必要があります:

dtrace -p $(pgrep -x mysqld) -F -n 'pid$target:mysqld::entry{} pid$target:mysqld::return{}' 

いくつかの出力の例として、InnoDBはアイドル時でもかなりチャットです:

2 -> sync_arr_wake_threads_if_sema_free  
6 -> os_event_reset       
2 -> os_mutex_enter      
6 <- os_event_reset       
2 <- os_mutex_enter      
6 -> pfs_mutex_exit_func     
6 <- pfs_mutex_exit_func     
2 -> os_mutex_exit      
6 -> os_event_reset       
2 <- os_mutex_exit      
6 <- os_event_reset       

MySQLディスパッチャに入るクエリを見ることができます!

dtrace -p $(pgrep -x mysqld) -F -n 'pid$target:mysqld:*dispatch_command*:entry{printf("Query: %s\n", copyinstr(arg2));}' 

出力例:

CPU FUNCTION         
0 -> dispatch_command(enum_server_command, THD*, char*, unsigned int) Query: SHOW VARIABLES LIKE 'pid_file' 

私はそれを信じているが、特定のクエリがを実行しながら、が起こるの関数呼び出しをリッスンするためのDTraceの能力の範囲内でもあります。たとえば、mysqld:*dispatch_command*:entryがクエリがいくつかの条件に一致する場合にスレッドローカル変数を初期化し、その変数が定義されている間にpid$target:mysqld::entry|returnを印刷することができます。対応するmysqld:*dispatch_command*:exitまたは同様のものは、その変数を定義解除することができます。別のスレッドで作業が発生することを期待している場合は、代わりにグローバル変数を使用することもできます。上記の具体例を書いていないため申し訳ありません

。私自身のMySQLはホースされており、私のDTraceの本はオフィスにあります。

ブレンダン・グレッグ、DTraceToolkitの著者はそれを作っているのsyscalls何、その読み込みと書き込みされているどのように大きな、プロセスがページフォルトが発生したされているかどうかを見るためsome one-linersなど、あなたの誤ったプロセスを監視するために有用である可能性がある多くのサンプルスクリプトを提供し、しかし、DTraceをより完全に学ぶなら、1ライナーよりもはるかに優れています。私はここに提示


スクリプトは、ベン・ロックウッドの記事、Examining MySQL in real time using DTraceに提示したものに基づいています。読むには無料登録が必要です。

私はブレンダン・グレッグの記事から、このツールについて学び、そしてブレンダンのDTrace bookからのDTraceについての詳細を学びました。ウサギの穴がどれくらい深くなっているかを知りたいのなら、この本を強くお勧めします。

関連する問題