SOFTELメモ Developer's blog

会社概要 ブログ 調査依頼 採用情報 ...
技術者募集中

【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のバグ報告はきれいに書いてありますね。上に書いたのは、自分のところで発生した場合の例ではなくて、バグ報告の再現手順そのままです。

関連するメモ

コメント