Naoya Murakami
visio****@gmail*****
2013年 8月 27日 (火) 20:01:06 JST
お世話になっております。村上です。
>count(*)なら最適化されると思いますが、count()の中
>身がカラム名だと最適化していなかった気がします。
あ、そうなんですね、勘違いしていました。
インデックスアクセスのみでレコードが特定できれば、カラム名指定してもいいものと
思いこんでいました。ちゃんと、カウントスキップ確認すればよかったですね。
>> mysql> select count(guid) from CombinedData where match(content)
>> against('事件' IN BOOLEAN MODE) and
orgId='ee15e1b414ad4329b7d14c857bc91644'
>> and objId='e9823fae423b4b56859ba98cb8a3a8dc';
>> +-------------+
>> | count(guid) |
>> +-------------+
>> | 172 |
>> +-------------+
>> 1 row in set (0.52 sec)
>> 最適化きいてないのにラッパーよりかなりはやいなぁ。。
>こっちもカラムアクセスが速いのが効いているんだと思います。
> > mysql> SHOW STATUS LIKE 'Mroonga_count_skip';
>> +--------------------+-------+
>> | Variable_name | Value |
>> +--------------------+-------+
>> | Mroonga_count_skip | 0 |
>> +--------------------+-------+
>> 1 row in set (0.00 sec)
>count(*)にすると↑
>の最適化が効いてさらに速くなると思います。
>(なるといいな。。。)
あれ?match ... against and col = のケースでも、カウント最適化動くんですか?
この場合、MySQL的には、フルテキストインデックスしか使われず、
残りのAND条件がインデックスアクセスできず、カウント最適化は
動かないものと思っていました。
order by limitの最適化と同じように、intとvarcharのequalは最適化される?
と、いうわけで、若干しつこくなっちゃいますが、追試しました。
そういえば、前は後ろで300Gぐらいのファイルを解凍しており、
結構ioが奪われていたかもしれず、
今回の追試結果は、前より全体的にはやくなっています。
よって、最適化有無の速度差が見えにくいです。というか見えません。。
手持ちの非常にでかいデータベースのインデックス構築ができたら(できたらいいな)、
order by limitの最適化も含めて、また検証してみたいと思っています。
以下は、追試結果です。
----------------------------------------
mysql5.6.13 クエリキャッシュ無効
mysql> select count(guid) from CombinedData where match(content)
against('事件' IN BOOLEAN MODE);
+-------------+
| count(guid) |
+-------------+
| 89072 |
+-------------+
1 row in set (0.03 sec)
mysql> SHOW STATUS LIKE 'Mroonga_count_skip';
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| Mroonga_count_skip | 0 |
+--------------------+-------+
1 row in set (0.00 sec)
たしかに、このケースでは、カウント最適化うごかなかったのですね。
失礼しました。
mysql> select count(*) from CombinedData where match(content) against('事件'
IN BOOLEAN MODE);
+----------+
| count(*) |
+----------+
| 89072 |
+----------+
1 row in set (0.02 sec)
mysql> SHOW STATUS LIKE 'Mroonga_count_skip';
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| Mroonga_count_skip | 1 |
+--------------------+-------+
1 row in set (0.00 sec)
最適化できています。が、もとからはやいからほとんどかわりません!
mysql> select count(guid) from CombinedData where match(content)
against('事件' IN BOOLEAN MODE) and orgId='ee15e1b414ad4329b7d14c857bc91644'
and objId='e9823fae423b4b56859ba98cb8a3a8dc';
+-------------+
| count(guid) |
+-------------+
| 172 |
+-------------+
1 row in set (0.40 sec)
mysql> SHOW STATUS LIKE 'Mroonga_count_skip';
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| Mroonga_count_skip | 0 |
+--------------------+-------+
1 row in set (0.00 sec)
mysql> select count(*) from CombinedData where match(content) against('事件'
IN BOOLEAN MODE) and orgId='ee15e1b
414ad4329b7d14c857bc91644' and objId='e9823fae423b4b56859ba98cb8a3a8dc';
+----------+
| count(*) |
+----------+
| 172 |
+----------+
1 row in set (0.33 sec)
mysql> SHOW STATUS LIKE 'Mroonga_count_skip';
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| Mroonga_count_skip | 0 |
+--------------------+-------+
1 row in set (0.00 sec)
若干はやくなっていますが、誤差のようなもので、カウントスキップも
インクリメントされず、カウント最適化は動いてないように見えます。
mysql> select count(guid) from CombinedData where match(content)
against('事件 + orgId:ee15e1b414ad4329b7d14c857bc91644 +
objId:e9823fae423b4b56859ba98cb8a3a8dc' IN BOOLEAN MODE) ;
+-------------+
| count(guid) |
+-------------+
| 172 |
+-------------+
1 row in set (0.06 sec)
mysql> SHOW STATUS LIKE 'Mroonga_count_skip';
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| Mroonga_count_skip | 0 |
+--------------------+-------+
1 row in set (0.00 sec)
mysql> select count(*) from CombinedData where match(content) against('事件 +
orgId:ee15e1b414ad4329b7d14c857bc91
644 + objId:e9823fae423b4b56859ba98cb8a3a8dc' IN BOOLEAN MODE) ;
+----------+
| count(*) |
+----------+
| 172 |
+----------+
1 row in set (0.06 sec)
mysql> SHOW STATUS LIKE 'Mroonga_count_skip';
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| Mroonga_count_skip | 1 |
+--------------------+-------+
1 row in set (0.00 sec)
againstの中でgroongaのクエリ構文指定する方法でもカウント最適化がうごきました!
が、やはり、最適化うごいていない場合もほとんど限界まではやくて差が見えないように思えます。
もっとデータを大きいのにすれば、このケースはさらにはやくなるのかもしれませんね。
以上、よろしくお願いします。