MySQL の filesort プチテクニック
http://d.hatena.ne.jp/kazuhooku/20081208/1228707040
ORDER BY で困った時にやってみよう。
そもそも now() と sysdate() ではなにが違うのか?
11.5. 日付時刻関数
http://dev.mysql.com/doc/refman/5.1/ja/date-and-time-functions.html
によると
SYSDATE() は、それが実行された時間を戻します。これは NOW() の動作によって異なり、ステートメントが実行を開始する時間を示す定数時間を戻します。( ストアド ルーチンまたはトリガ内で、NOW() はルーチンまたはトリガ文が実行を開始する時間を戻します。)
そのほか、 SET TIMESTAMP 文は NOW() によって戻された値に影響を及ぼしますが、SYSDATE() によって戻された値には影響しません。つまり、バイナリログのタイムスタンプ設定は、SYSDATE() の呼び出しには効果をもたらさないということになります。
なんのこっちゃ?って感じですが、そのすぐ下の例を見るとすこし分かった気になります。
mysql> SELECT NOW(), SLEEP(2), NOW(); +---------------------+----------+---------------------+ | NOW() | SLEEP(2) | NOW() | +---------------------+----------+---------------------+ | 2006-04-12 13:47:36 | 0 | 2006-04-12 13:47:36 | +---------------------+----------+---------------------+ mysql> SELECT SYSDATE(), SLEEP(2), SYSDATE(); +---------------------+----------+---------------------+ | SYSDATE() | SLEEP(2) | SYSDATE() | +---------------------+----------+---------------------+ | 2006-04-12 13:47:44 | 0 | 2006-04-12 13:47:46 | +---------------------+----------+---------------------+2回目のSYSDATEは、SLEEP をいれた分だけ、遅れた時間が表示されます。
select count(*) from event_master \ where event_start_datetime < subdate (now(),1 );
select count(*) from event_master \ where event_start_datetime subdate (sysdate(),1 );
そのほか、 SET TIMESTAMP 文は NOW() によって戻された値に影響を及ぼしますが、SYSDATE()によって戻された値には影響しません。
つまり sysdate() を使うと、レプリケーションでマスター側とスレーブ側とで、差異が生じるということを意味します。実際
5.4.1.6. レプリケーションとシステム機能
http://dev.mysql.com/doc/refman/5.1/ja/replication-features-functions.html
を読むと、そのあたりのことが書かれています。これを利用して、レプリケーションの遅延を計るぜ!ってことをやる方もおられるようです。
行ベースのロギングを使用している場合には、この点の心配はありません
の記載があるように、binlog_format を ROW にするとレプリケーションセーフになるようですが試してません。基本的に sysdate() じゃなきゃだめだ!ってことはないと思うので、
- パフォーマンス
- レプリケーション機能
を考慮して、自分でプログラムを書くときは、now() を、sysdate() で書いちゃったものをレプリケーション構成で動かしたい場合は、my.cnf に
[mysqld]
sysdate-is-now
を設定して、再起動。これが無難に思えます。こうすると、 sysdate() が now() として動作するので、プログラムの書き換えなしに、上記の対応が可能となります。
他にも、レプリケーションセーフでない(場合によっては、MySQLのバージョンに依存)関数が複数あります。事前に使用する MySQLのバージョンを確認し、マニュアルを参照しておいた方がよさそうです。
MySQL Multi-Master Replication Manager
http://code.google.com/p/mysql-master-master/
via どこだっけ?
む? 試してみたいかも……
MySQL Performance Blog
http://www.mysqlperformanceblog.com/mysql-performance-presentations/
MySQL のパフォーマンスTIPSなどに触れたプレゼンテーション。バージョンによる違いや、Innodb でのパフォーマンスTIPSなども。
MySQLの高度な管理とチューニングテクニック
http://www.atmarkit.co.jp/flinux/rensai/mysql11/mysql11a.html
ZMR for MySQL(Zamanda Recovery Manager)
http://www.zmanda.com/
米Zmanda、オープンソースのMySQL用バックアップソフトをリリース
http://enterprise.watch.impress.co.jp/cda/foreign/2006/09/28/8729.html
via http://memo.xight.org/2006-10-31-2
気になる……
MySQL で HA
http://www.seriema-systems.com/mysql-ha/
気になるけど、まだ Alpha版
MYCOMジャーナルで紹介されていた Execute Query を試してみる。
これは便利! MySQL/PostgreSQLにも対応 - RDBMS操作ツール"Execute Query"
http://journal.mycom.co.jp/articles/2006/09/22/executequery/
このツールのダウンロードは
http://executequery.org/download.jsp
から行なえる。今回も Debian(sid)にインストールしてみる。ここでは
eqsetupj-v3.0final.jar (Java installer - any OS)
とやらを選択。Java 1.5系じゃないと動かないらしいので
$ export JAVA_HOME=/usr/lib/j2sdk1.5-sun/
$ sudo /usr/lib/j2sdk1.5-sun/bin/java -jar eqsetupj-v3.0final.jar
としてインストーラーを起動。普通にインストールすると
/usr/local/share/executequery
にインストールされる。起動用のシェルスクリプトが用意されているので
$ /usr/local/share/executequery/eq.sh
で実行する。ただ、default のJAVA_HOMEが Java 1.5 に向いてないので、以下のように書き換え。
#!/bin/sh
# Java heap size, in megabytes
JAVA_HEAP_SIZE=128
# default java location
# change this to point to the local java installation
DEFAULT_JAVA_HOME="/usr/lib/j2sdk1.5-sun"
if [ "$JAVA_HOME" = "" ]; then
JAVA_HOME="$DEFAULT_JAVA_HOME"
fi
exec "$JAVA_HOME/bin/java" -mx${JAVA_HEAP_SIZE}m -jar "eq.jar" &
これで JAVA_HOMEが設定されていなくても、上記のスクリプトだけで起動できる(もちろん、/usr/lib/j2sdk1.5-sun に Java-1.5 が事前に導入されている必要はある)
$ /usr/local/share/executequery/eq.sh
Unable to access jarfile eq.jar
だめだった orz
うーん、/usr/local/executequery に移動して起動することが前提になってるのか……さらに
#!/bin/sh
# Java heap size, in megabytes
JAVA_HEAP_SIZE=128
# default java location
# change this to point to the local java installation
DEFAULT_JAVA_HOME="/usr/lib/j2sdk1.5-sun"
if [ "$JAVA_HOME" = "" ]; then
JAVA_HOME="$DEFAULT_JAVA_HOME"
fi
cd /usr/local/share/executequery
exec "$JAVA_HOME/bin/java" -mx${JAVA_HEAP_SIZE}m -jar "eq.jar" &
に書き換えた。
動いた :-)
これだけだと実はだめで、ちゃんとドライバも用意してやる必要がある。PostgreSQL ならこんな感じ
# apt-get install libpg-java
これで、一番左の
Drivers を選択して、JDBC Driversの一覧を表示させ「ODBC Driver」のところで右クリックか
をクリックして、「New Driver」を追加し、以下のような感じで設定。
この状態で、「Connections」に戻って、普通に User/Pass, 接続先, DB名などを指定してやると繋がる。
既存のDBからER図も生成できて面白いね :-)
ただ、やっぱりMYCOMジャーナルの記事でもあったように、ドライバの設定が億劫かなぁ? Javaの知識がある程度ないと使えないのは辛い(^_^;