Skip to content
This repository has been archived by the owner on Sep 4, 2020. It is now read-only.
nonylene edited this page Oct 20, 2018 · 2 revisions

MySQL5.7が欲しい

Download MySQL APT Repository 5.7もちゃんとaptとかyumで入る、めでたい

クエリキャッシュ

show variables like 'query_cache_%';
set global query_cache_size = 1000000;

https://www.checksite.jp/mysql-query-cache-size/

innodb とか max_connections

[mysqld]
max_connections = 1024
innodb_buffer_pool_size = 1G
innodb_flush_log_at_trx_commit = 0
innodb_flush_method=O_DIRECT

スロークエリ

/etc/my.cnf

[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/mysql-slow.log
long_query_time = 0.5 #slow query time
log-queries-not-using-indexes

すると吉。timeを0にすると全部のクエリ解析できます。

解析

percona toolkit

percona toolkit を入れると良い

$ pt-query-digest [slow-query-file]

mysqldumpslow

$ mysqldumpslow -s t mysql-slow.log > slow-parsed.log

とかでクエリあたりにかかる時間がわかる。

詳細なクエリの解析

show profile for query 1で最新実行クエリのプロファイリングが見れる。これでそのクエリのどの段階に時間がかかっているのかがわかる。
レファレンスのリンク

もっと詳細に見たいなら、information_schemaのprofiling tableを利用して、

# query実行後
set @query_id = 1
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;

でできる。(.sqlとして実行したほうがいいかも)

またあるクエリの実行後にshow statusコマンドで、MySQLが行った操作のカウンタが見れる。

初期状態でデータベースを選択

rootさんのpasswordというパスワードでisuconデータベースを見る場合

$ mysql -uroot -ppassword isucon

schemaを見る

show full columns from (table名);

でスキーマが見れる。

インデックスを張る

CREATE TABLE テーブル名(カラム名 型,カラム名 型, ... INDEX(カラム名);
or
CREATE INDEX インデックス名 ON テーブル名(カラム名);
or
ALTER TABLE テーブル名 ADD INDEX インデックス名(カラム名);

Note:

  • 何かしらの操作が適用された結果にはインデックスは利用できないので注意すること(例えばwhere id +4 = 5とかDATE(created_at)とか。)
  • 複合(複数列)インデックスを作成する際は選択性の高いカラムから順にインデックスを作っていく。また、作成した後は可能ならちゃんとそれが効用を発揮しているかexplainあたりで確認しよう(後述)
  • 必要な行がすべてインデックスに含まれていれば、テーブル本体をスキャンすること無くインデックススキャンのみで済ませることができ、高速になる(カバリングインデックス)。使えないか検討してみる。

MySQL

MySQLは複数のmy.cnfから設定を読み込んている場合があるのでまず確認。

Neko-no-te% mysql --help | grep my.cnf
                      order of preference, my.cnf, $MYSQL_TCP_PORT,
/etc/my.cnf /etc/mysql/my.cnf /usr/etc/my.cnf ~/.my.cnf

現在の設定値などを確認するコマンド

mysql$> SHOW GLOBAL STATUS;
mysql$> SHOW GLOBAL VARIABLES;

この2つの概念の違いはあんまりわかってないけど、設定値はこの2つ叩けばとりあえず出てくる。

ただ、このあたりの結果を見ても解釈、解決方法がわからないとあんまり意味がない。 TODO: 調べる

この辺参考に適当なパラメータ入れる?

http://qiita.com/muran001/items/14f19959d4723ffc29cc
http://www.oracle.com/technetwork/jp/ondemand/database/mysql/mysql-perftun-1484759-ja.pdf
http://blog.layer8.sh/ja/2011/12/23/mysql%E3%82%92%E9%AB%98%E9%80%9F%E5%8C%96%E3%81%97%E3%81%9F%E3%81%84%E3%81%A8%E3%81%8D%E3%81%AE%E3%83%81%E3%83%A5%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0/
http://enterprisezine.jp/dbonline/detail/3829

TODO:上のリンク読んで秘伝のmy.cnfのテンプレ作っとく とりあえずkazeburoという偉い人が設定したやつ

innodb_buffer_pool_size = 1G
innodb_flush_log_at_trx_commit = 0
innodb_flush_method=O_DIRECT

反映 service mysqld restart

テーブル、データのバックアップ