日々精進

新しく学んだことを書き留めていきます

実践ハイパフォーマンスMySQLまとめ2

・explain句
rowsはindexから推測した一致する行数。これが実際の行数と大きく違う場合はoptimize tableを実行すると速くなることがある。
使用できるインデックスが複数あった場合、一番一致する行が少ないと推定した条件のインデックスを使用する。
例:first_nameとlast_nameカラムにそれぞれインデックスを張ってある状態で以下のクエリを実行する
select * from users where last_name = '鈴木' and first_name = '次郎'
インデックスからfirst_name = '次郎'の条件の方が一致する行が少ないと推定されたらfirst_nameのインデックスのみ使う。
この例でわかるように、どのインデックスを使うかは使用するデータによる。
どのインデックスを使うか指定したい場合はuser index句を使う。


・テーブルサイズがわかっている場合、結合するテーブル数が多い場合はテーブルを結合する順序を指定しよう
MySQLはテーブルの効率的な結合順序を正しく推定することが苦手。
テーブル結合は結合途中に取り出す行数が少ないほど速い。
例えば、以下のクエリの場合

select *
from  users, people, items
where users.person_id = people.id
  and people.item_id = items.id

usersとpeopleを結合したら1000行が取り出され、peopleとitemsを結合したら10000行が取り出されるとする。この場合usersとpeopleを先に結合する方が速い。
結合するテーブル数が多いと効率的な結合順序を推定するのにかなり時間がかかることがある。
結合順序を指定するには straight_joinを使えばいい。


・slow query logやmysqldumpslowを使えば遅いクエリを簡単に特定できる
MySQLにインデックスを使わせる方法

一つのクエリを二つに分解する
ORの代わりにUNIONを使う


・バックアップツール
mysqldump 簡単に使えるが、バックアップファイルが大きくなる。テーブルロックもすべてロックするか全くしないかの二択。
mysqlhotcopy バックアップファイルは小さくなる。すべてのテーブルをロックして、読み出しが終わったテーブルからロックを解除する。
mysqlsnapshot バックアップファイルはだいぶ小さくなる。ロックについては詳しく書いてない。