2015年09月07日

#1016 - Can't open file: 'table_name.MYI'. (errno: 126)

 というエラーが出てmysqlの特定テーブルが使えなくなりました。テーブル名.MYIファイルとは、インデックスデータとテーブルの統計情報が格納されているものらしいです。
 REPAIRしようとするも、これも同じエラーでNG。
 myisamchk を使うと修復できるようなのですが、さくらインターネットでこれの使い方が分からず、おそらく使えないため、結局断念しました。
 そこでバックアップから修復しようとしたのですが、定期バックアップを見てみると文字化けしていて愕然。
 これも直さないと、と調べてみるとmysqldumpに--default-character-set=binaryをつければよろしい、という情報があるのでやってみたのですが、「Character set 'binary' is not a compiled character set and is not specified」というエラーでこれもNG。
 phpmyadminからなら普通にエクスポートできるのですが、これも未だ解決法が分からず。
 今回はたまたまテーブルが小規模でローカルにもデータがあったため、なんとか事なきを得ましたが、結局根本的な問題は解決していません。
 困った・・。
 phpmyadminは内部的にどういうコマンドでエクスポートしているのでしょう? mysqldumpだと思うのですが・・。
posted by ふみこ at 15:52| DB

2015年08月08日

mysqldump unknown option "--no-beep"

 mysqldumpを使おうとして、

mysqldump unknown option "--no-beep"

 というエラーが出ました。
 軽くググってみると、解決法はこちら。

mysql - mysqldump unknown option no beep - Stack Overflow

 my.iniの中に

[client]
no-beep

 という箇所があるので、

#no-beep

 とコメントアウト。これでうまく行きました。

 わたしの環境(Windows)では、my.iniはmysql\MySQL Server 5.6に、mysqldumpはmysql\MySQL Server 5.6\binにありました。
 特定テーブルのみをダンプする場合は、

mysqldump --default-character-set=utf8 -u root -p db_name table_name1 table_name2 > dump.sql

 でOK。
タグ:MySQL
posted by ふみこ at 18:44| DB

2014年04月23日

非正規化によるMySQLのパフォーマンス改善

 非正規化によるパフォーマンス改善、などと書くと、多くの真面目なプログラマーの方にフルボッコにされそうな酷いお話です。わたしも大嫌いです、こういう発想は。
 ただ、今扱っているアプリケーションで、DB周りが非常に重くなってきてしまい、indexの検討など通常考えられることを色々試した挙句、最後にこの禁じ手?で一気に解決したので、メモだけしておきます。
 もともとのテーブルは、

CREATE TABLE `TABLE_NAME` (
`PRIMARY_KEY` int(11) NOT NULL auto_increment,
`HOGE` varchar(255) NOT NULL default '',
`FUGA` int(11) NOT NULL default '0',
`BIG_COLUMN` longtext NOT NULL,
PRIMARY KEY (`WORD_NUM`),
)

 みたいな感じで(実際は沢山カラムがあります)、まぁごく平凡なテーブルでした。参照も更新もされるし、数十件程度をまとめて取ってくる場合もあります。
 問題はこのBIG_COLUMNというlongtextです。
 最初のうちは良かったのですが、件数が増えるに従って、単純なSelectでも非常に時間がかかるようになりました。もちろん、必要な場合以外はこのカラムを選択対象に入れていないのですが、それでも重いです。
 このカラムは主キーをキーに一行だけ取得または更新・挿入する場合のみに見られるものなので、そうした場合だけ選択対象に入れています。
 このカラムと全然関係ない、例えば
SELECT HOGE,FUGA FROM TABLE_NAME WHERE PRIMARY_KEY=5
 のようなクエリでもパフォーマンスが低下しました。
 巨大なテクストが入っているので、仕方ないのかもしれません。
 先述の通り、indexの再検討や複合indexなど、色々思いつくことをやってみたのですが、ふと考えて、テーブルを分割してみました。

CREATE TABLE `TABLE_NAME` (
`PRIMARY_KEY` int(11) NOT NULL auto_increment,
`HOGE` varchar(255) NOT NULL default '',
`FUGA` int(11) NOT NULL default '0',
PRIMARY KEY (`WORD_NUM`),
)

CREATE TABLE `TABLE_NAME2` (
`PRIMARY_KEY` int(11) NOT NULL auto_increment,
`BIG_COLUMN` longtext NOT NULL,
PRIMARY KEY (`WORD_NUM`),
)

 みたいな感じです。もう一つのテーブルは、行数は最初のテーブルと全く同じ、主キーも同一で、主キーと巨大カラムの二つだけがあります。
 選択する時は結合するのではなく、必要な場合にのみTABLE_NAME2に対して改めてクエリを発行します。基本的にTABLE_NAME2は一行単位でしか参照・更新することがありません。
 すると当たり前ですが、パフォーマンスが劇的に向上しました。
 アプリケーション側で配慮すべき要素が少し増えましたが、幸いそれほど入り組んだシステムでもないので、修正も最小限で済みました。

 非常に泥臭いというか、恥ずかしいというか、できればやりたくないタイプの方法ですが、この場合、非正規化といっても同じカラムがあちこちにできてしまうという程のものではなく、単純にテーブルを縦に割ったようなものです。まぁ、みっともないですが、ギリギリ許される範囲かな・・とも思います。実際、この泥臭い方法がなければ切り抜けられなかったので・・。
posted by ふみこ at 11:15| DB
↓応援クリックお願いします☆
ブログランキング・にほんブログ村へ