2012年11月18日日曜日

「MySQLを辞めるべき○個の理由」 或いは 「本当にあったMySQLの怖い話」


  1. InnoDBが外れることがある
    1. innodb_data_file_pathを迂闊に書きかけてそのまま再起動すると、InnoDBストレージエンジンがシレっと外れる
    2. しかもCREATE TABLE ENGINE=InnoDBは、MyISAMに代替して、シレッと継続する。気づかないと、トランザクションが効かなくなって迷宮入りする。
    3. InnoDBテーブルは読めなくなる。SELECT等を発行して始めて発覚する。
  2. レプリケーションは止まることがある
    1. http://nippondanji.blogspot.jp/2009/03/MySQL10.html
    2. しかも復旧が面倒臭い
    3. http://d.hatena.ne.jp/rockstar2007/20110128/1296230962
  3. MyISAMは壊れることがある
    1. http://dev.MySQL.com/doc/refman/4.1/ja/corrupted-myisam-tables.html
  4. InnoDBは壊れることがある
    1. http://dev.MySQL.com/doc/refman/5.1-olh/ja/innodb-backup.html
  5. 大量のレコードを、単一トランザクションでINSERTすると、激遅い
    1. http://dev.MySQL.com/doc/refman/4.1/ja/insert-speed.html 「挿入の速度をあげる方法」という項目の存在
  6. 大量のレコードを、単一トランザクションでDELETEすると、激遅い
    1. http://blog.livedoor.jp/sasata299/archives/51363104.html
    2. http://d.hatena.ne.jp/bco/20101222/1293023066
    3. http://dev.MySQL.com/doc/refman/5.1/ja/delete-speed.html
      1. 行の削除に要する時間は、完全にインデックス数に比例します
        1. ってインデックスの意味ねーだろ。
      2. テーブル内のすべての行を削除する場合は、TRUNCATE TABLE tbl_name 
      3. のほうがDELETE FROM tbl_nameを使用するより高速です。「TRUNCATE 構文」を参照してください。
        1. ってそんなケースがどんだけあるんだゴルア

    1. 新しいテーブルに必要なレコードだけCREATEしなおしてね。とかそんなのメンテ入れなきゃ出来ねえだろうがゴルア
  7. ALTER TABLEは恐ろしく時間がかかることがある。
    1. http://d.hatena.ne.jp/LukeSilvia/20090315/p1
  8. UPDATE文のWHEREをANDと書き間違えると、全件書き換えてしまう
    • UPDATE テーブル SET ナンチャラ=カンチャラ WHERE どうたら
      • UPDATE テーブル SET ナンチャラ=カンチャラ AND どうたら
      • 全てのレコードの、ナンチャラには0が入ります。
    • http://dev.MySQL.com/doc/refman/5.1-olh/ja/type-conversion.html 「オペランドを適合化するため、型変換が起こります」頼んでねーよ。
      • PHPと組むと、迷宮入りする可能性があります。
    • 正直、SQLの仕様として、WHEREを必須にするべきでしょう。データベースの意味を考えれば、「全レコード置換」がどれほどの頻度なのか。
  9. 一部のカラム型は、not null制約が、効果がない。
    1. 例えばdatetime型は、0年0月0日が入ります。実際の処理を考えれば、nullと何が違うんだって話。もちろんおお違いです。むしろ面倒臭い。nullの判定に加えて、0年の判定をしなければならなくなる。
      1. PHPと組むと、実は==0で判断できてしまう。何がしたいんだPHP+MySQL。
  10. カラム長を超えるデータを、勝手に丸める。
    1. 文字列は、ブツ切れる
    2. 整数は、2^Xに収まる
    3. って言うか、エラーだすとこだろゴルア
    4. って言うか、SET SQL_MODE= TRADITIONAL ってやるといいらしい。なんでそれがデフォルトになってないのか個一時間。
  11. なんかトランザクションが遅いなー、と思ったら、flush tablesをやったら早くなった気がする??
    1. http://dev.MySQL.com/doc/refman/5.1/ja/flush.html
    2. 「query cacheもします」って??
    3. 「メモリ使用を向上させる為にクエリ キャッシュをデフラグ」
    4. vacuum要りません。で売ってるのに、デフラグとか言っちゃだめじゃん!
MySQLは、ストレージエンジンという概念を導入していて、表面上は先進に見えますが、それ故に、細かいオーバーヘッドが点在していて、簡単にしかも大幅に性能が落ちます。そんなことに気を付けながら書かなきゃならないなら、「offset 1000以上は禁止」とかしてくれたほうが余程マシです。

強烈な型変換は、本当に何がしたいのか判らない。「データを保存する」という要職にありながら、データの改変をするって意味判りません。オフィシャル言い訳  http://dev.mysql.com/doc/refman/5.1/ja/constraint-invalid-data.html んん、やっぱりストレージエンジン駄目だな。そしてfailsafeを誤解してる感。

正直、「「象牙の塔」リレーショナルデータベースシステム」と言わざるを得ません。

※象牙の塔は、どこぞの本で読んで感銘を受けたフレーズです。
http://gogen-allguide.com/so/zougenotou.html

文句を言うなら使うなって?もちろん使いませんよ。ここ最近の案件で、小生の意思でMySQLを「選んだ」ことは一度もありません。決まっちゃってるから使ってるだけ。お客がゴネるから使ってるだけ。