【MySQL】SQL_CALC_FOUND_ROWS と GROUP BY を同時に指定すると発生する不具合
問題
こんなテーブルがありまして
CREATE TABLE `buggy_sm` ( `id` int(11) NOT NULL AUTO_INCREMENT, `int1` int(11) NOT NULL DEFAULT '0', `kat` int(11) NOT NULL DEFAULT '0', `date_from` date NOT NULL DEFAULT '0000-00-00', `date_to` date NOT NULL DEFAULT '0000-00-00', `dict` tinyint(1) NOT NULL DEFAULT '0', PRIMARY KEY (`id`), KEY `dict` (`dict`), KEY `multi` (`kat`,`int1`,`date_from`,`date_to`,`dict`) ) ENGINE=MyISAM;
こんなデータを入れまして、
INSERT INTO `buggy_sm` VALUES (1,21,101,'0000-00-00','2006-09-26',0), (79,18,102,'0000-00-00','2006-10-23',0), (101,7153,201,'0000-00-00','2006-09-08',0), (4362,10365,324,'0000-00-00','2007-05-29',0), (19522,892,329,'0000-00-00','2008-11-15',0), (4382,4268,503,'0000-00-00','2006-09-05',1), (5088,728,504,'0000-00-00','2006-09-05',0), (6110,3798,505,'0000-00-00','2008-09-05',0), (7315,6205,506,'0000-00-00','2008-09-05',1), (8394,6732,507,'0000-00-00','2008-09-05',0), (8593,6954,508,'2006-09-13','2008-09-08',0), (8708,9625,509,'2006-09-10','2008-09-05',1), (9179,14811,510,'0000-00-00','2006-09-05',0), (13076,3334,511,'2006-10-02','2008-09-27',1), (13086,15319,512,'2006-09-15','2008-09-10',0), (13216,3479,513,'0000-00-00','2008-09-05',1), (13783,4403,514,'0000-00-00','2006-09-06',1), (29337,11102,516,'0000-00-00','2006-09-09',1), (29857,8606,518,'0000-00-00','2008-09-08',0), (29886,8267,520,'0000-00-00','2006-12-29',0), (13866,2984,601,'0000-00-00','2006-09-08',0), (14082,17253,602,'2006-09-13','2008-09-08',0), (14372,18772,604,'0000-00-00','2006-09-05',0), (14930,8086,605,'0000-00-00','2006-09-06',0), (14974,2842,606,'0000-00-00','2006-09-06',0), (29031,719,610,'0000-00-00','2006-09-11',0), (32699,18916,611,'2006-09-17','2008-09-12',0), (3917,4374,615,'0000-00-00','2006-09-05',0), (32366,3300,633,'2007-02-01','2009-01-27',0), (15054,13146,801,'0000-00-00','2006-09-07',0);
こんな風に、SQL_CALC_FOUND_ROWS と GROUP BY のある問い合わせを送ると、おかしな結果が返ってくる。
> SELECT SQL_CALC_FOUND_ROWS `kat` FROM `buggy_sm` WHERE dict=0 GROUP BY `kat` LIMIT 2; +-----+ | kat | +-----+ | 0 | +-----+ 1 row in set (0.00 sec)
SQL_CALC_FOUND_ROWS を使わなかったら、正しい結果が返ってくる。
> SELECT `kat` FROM `buggy_sm` WHERE dict=0 GROUP BY `kat` LIMIT 2; +-----+ | kat | +-----+ | 101 | | 102 | +-----+ 2 rows in set (0.00 sec)
なんなんでしょ、これ。
答え
不具合だそうです。
Bug #62372 Wrong query results with SQL_CALC_FOUND_ROWS, GROUP BY, LIMIT and Using index
問題のような SQL_CALC_FOUND_ROWS と GROUP BY を組み合わせたSQLを実行すると、異常な結果が返ってくるというものです。
インデックスが絡んでいると、LIMITの値などによって、問い合わせがおかしな最適化のされ方をして、異常な結果が返ってきます。
発生が報告されているのが 5.5.15, 5.5.17 と、新しいバージョン。
まだ直っていないようなので、注意。
「GROUP BY 付きで SELECT SQL_CALC_FOUND_ROWS」なんて、実装側としては複雑で大変で、開発者さんも苦労しているのでしょうか。そんなややこしいSQLやめてくれ と思っているかもしれません。
しかし、MySQLのバグ報告はきれいに書いてありますね。上に書いたのは、自分のところで発生した場合の例ではなくて、バグ報告の再現手順そのままです。
コメント