2011-06-16
■[生活とLife]光の彼方には何があるのだろう?ニフラム…(自分に手をかざしながら)
2ヶ月ちょい前にMySQLの不思議なbugに遭遇したので報告させて頂きます。
- MySQLのバージョン: 5.1.42-community-log
- OS: CentOS5 Final
- 現象: order by PRIMARY_KEY desc limit N で該当するレコードが取得できない
どのような事が起こるかは、http://stackoverflow.com/questions/2844699/mysql-order-by-and-limit-gives-wrong-resultからコピペ。
Works correctly: mysql> SELECT id, created_at FROM billing_invoices WHERE (billing_invoices.account_id = 5) ORDER BY id DESC ; +------+---------------------+ | id | created_at | +------+---------------------+ | 1336 | 2010-05-14 08:05:25 | | 1334 | 2010-05-06 08:05:25 | | 1331 | 2010-05-05 23:18:11 | +------+---------------------+ 3 rows in set (0.00 sec) WRONG result when limit added! Should be the first row, id - 1336 mysql> SELECT id, created_at FROM billing_invoices WHERE (billing_invoices.account_id = 5) ORDER BY id DESC limit 1; +------+---------------------+ | id | created_at | +------+---------------------+ | 1331 | 2010-05-05 23:18:11 | +------+---------------------+ 1 row in set (0.00 sec) Works correctly: mysql> SELECT id, created_at FROM billing_invoices WHERE (billing_invoices.account_id = 5) ORDER BY created_at DESC ; +------+---------------------+ | id | created_at | +------+---------------------+ | 1336 | 2010-05-14 08:05:25 | | 1334 | 2010-05-06 08:05:25 | | 1331 | 2010-05-05 23:18:11 | +------+---------------------+ 3 rows in set (0.01 sec) Works correctly with limit: mysql> SELECT id, created_at FROM billing_invoices WHERE (billing_invoices.account_id = 5) ORDER BY created_at DESC limit 1; +------+---------------------+ | id | created_at | +------+---------------------+ | 1336 | 2010-05-14 08:05:25 | +------+---------------------+ 1 row in set (0.01 sec) Additional info: explain SELECT id, created_at FROM billing_invoices WHERE (billing_invoices.account_id = 5) ORDER BY id DESC limit 1; +----+-------------+------------------+-------+--------------------------------------+--------------------------------------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------------+-------+--------------------------------------+--------------------------------------+---------+------+------+-------------+ | 1 | SIMPLE | billing_invoices | range | index_billing_invoices_on_account_id | index_billing_invoices_on_account_id | 4 | NULL | 3 | Using where | +----+-------------+------------------+-------+--------------------------------------+--------------------------------------+---------+------+------+-------------+
ORDER BY だけなら問題ないが LIMIT を指定すると type が index から range にかわりなんかうんこ。
対策は force index するか created_at に index はっておいて created_at でソートすればよいと思います。
http://bugs.mysql.com/bug.php?id=37830 をみると2008年頃に fix したのに今年また大復活を遂げたみたいなのでMySQL5.1系つかってる人は注意したほうがよいでしょう。
話がかわりますが、僕は
をわり。
トラックバック - http://d.hatena.ne.jp/nTeTs/20110616/1308213898
リンク元
- 7 http://pipes.yahoo.com/pipes/pipe.info?_id=6ffca3d513899ee44c0d1201c766e92c
- 7 http://www.facebook.com/l.php?u=http://d.hatena.ne.jp/nTeTs/20110616/1308213898&h=859b1
- 6 http://reader.livedoor.com/reader/
- 5 http://pipes.yahoo.com/pipes/pipe.info?_id=5c957097ed152660234169b605fb3fa7
- 5 http://search.minakoe.jp/rsss/rsss.asp?pid=221627&plp=1&pd=2008/09/30&lid=3969&nlp=1&sd=2008/09/30&base=20&blp=1&bd=2008/09/30&multi=1&qry=perl
- 3 http://twitter.com/
- 2 http://a.hatena.ne.jp/kuzumix/
- 2 http://blog.zuzara.com/2006/07/20/98/
- 2 http://d.hatena.ne.jp/keywordmobile/ニフラム
- 2 http://ezsch.ezweb.ne.jp/search/?sr=0101&query=トゥルルル
