次のようにSLEEP()を利用するとわかり易いだろう。
mysql> SELECT SYSDATE(), SLEEP(100), SYSDATE(); +---------------------+------------+---------------------+ | SYSDATE() | SLEEP(100) | SYSDATE() | +---------------------+------------+---------------------+ | 2009-04-27 07:17:09 | 0 | 2009-04-27 07:18:49 | +---------------------+------------+---------------------+ 1 row in set (1 min 40.00 sec) mysql> SELECT NOW(), SLEEP(100), NOW(); +---------------------+------------+---------------------+ | NOW() | SLEEP(100) | NOW() | +---------------------+------------+---------------------+ | 2009-04-27 07:19:56 | 0 | 2009-04-27 07:19:56 | +---------------------+------------+---------------------+ 1 row in set (1 min 40.00 sec)
SYSDATE()では2つの結果が100秒異なっているのに対して、NOW()では同じ結果になっている。もしクエリにおいて一貫した値を取得したければ、SYSDATE()ではなくNOW()を使うといいだろう。
ちなみに、SYSDATE()とNOW()ではNOW()の方が高速である。なぜなら、結果をキャッシュするので実際に日付を求めるのは一度で済むからだ。とはいえ、SYSDATE()も十分高速なので実行回数がそれほど多くなければ問題にはならないのでそれほど気にする必要はない。例えば、実行回数が一億回などのように非常に多い場合には、次のように差が出てくる。
mysql> SELECT BENCHMARK(100000000,SYSDATE()); +--------------------------------+ | BENCHMARK(100000000,SYSDATE()) | +--------------------------------+ | 0 | +--------------------------------+ 1 row in set (3 min 29.46 sec) mysql> SELECT BENCHMARK(100000000,NOW()); +----------------------------+ | BENCHMARK(100000000,NOW()) | +----------------------------+ | 0 | +----------------------------+ 1 row in set (1.93 sec)
SYSDATE()はOracle互換のために実装されている関数だ。もし、上記のような厳密な違いが必要ないのであれば、--sysdate-is-nowオプションをつけてMySQLサーバーを起動するといい。そうすると、SYSDATE()を実行した場合にもNOW()と同じ振る舞いをし、実行速度もNOW()と同じように速くなる。
mysql> SELECT BENCHMARK(100000000,SYSDATE()); +--------------------------------+ | BENCHMARK(100000000,SYSDATE()) | +--------------------------------+ | 0 | +--------------------------------+ 1 row in set (1.91 sec)
僅かな差ではあるがNOW()の方が消費するリソースが少ないのは確かである。小さいところからコツコツと積み重ねていくのがエコの基本。MySQL DBAもエコでありたい。
systedate()はver5.0で仕様が変わったんで、ver4.1以下ではsysdate()= now()だったような気が。もう覚えてないけど。
返信削除