Rails で MySQL を使うときの注意点

Rails で MySQL を使うときの注意点

2007/07/24 9:29am

Rails のブログでも取り上げられていた、"Rubyisms - MySQL-dump" が面白かったので、特に興味深かった一時テーブルまわりの要約を載せてみる。要約、というか読みながら書いたメモそのまんまですが。

Rubyisms - MySQL-dump http://mysqldump.azundris.com/archives/72-Rubyisms.html

“select *” が多すぎる

ActiveRecord は、特に何も指定しないと select * で、すべてのカラムを取ってくる。SQL は動的に生成されて、どのカラムが存在するかチェックしているので、スキームが変更されても大丈夫。

でも、必要のないデータまで取ってきてしまう、という問題はあるよね。そして、何が無駄かっていうと、必要のないデータのために一時的なテーブルが使われるかもしれない、ってことなんだ(SQL を EXPLAIN してみて、“using temporary” となっていれば、そういう事態が発生しているサインだ)。

そういう場合は、SQL を二段階に分けるといい

では、ActiveRecord で select * を避けるにはどうするか?

文字列型がかなり無駄かも

たとえ TEXT 型(Migration だと :text 型)を使っていなくても、Migration で :string 型を使っているなら、気をつけた方がいい。

さて、MySQL ではメモリ上の一時テーブルには VARCHAR 型がない(「補足:メモリ上の一時テーブルには VARCHAR 型がない」参照)

だから、デフォルトの utf8 ではなく、latin1 などの多バイトではないエンコーディングを使うことも考慮した方がよい。そして、:string 型には必ず :limit を指定しよう。

以上、MySQL の一時テーブルの特性とか、知らないとどうにもならん部分が多い。他にも、

興味深い話題があります。あと、この要約が間違ってる可能性もあるので、是非原文も読むことをおすすめします。

補足:メモリ上の一時テーブルには VARCHAR 型がない

「メモリ上の一時テーブルには VARCHAR 型がない」という記述について、気になったので調べてみた。

Common Questions and Answers from Performance Tuning Webinars - Jay Pipes という記事にて、

  • A temporary table is implicitly created to handle a GROUP BY or ORDER BY clause and a VARCHAR column is in the SELECT statement
  • A temporary table is created explicitly which contains a VARCHAR column

In these cases, the length of the VARCHAR columns does come into play. Why? Because temporary tables in memory are actually just tables of the MEMORY storage engine. The MEMORY storage engine, for some reason, treats all VARCHAR(X) columns as CHAR(X) columns.

つまり、

ということのようだ。