これには 72 秒かかります。
SELECT distinct(meters.id)
FROM meters, meters_tags, houses_tags, tags
WHERE (
tags.name = "xxx" AND ((
meters_tags.tag_id = tags.id AND
meters_tags.meter_id = meters.id
) OR (
houses_tags.tag_id = tags.id AND
houses_tags.house_id = meters.house_id
)
)
);
これには 0.00 秒かかります。
SELECT distinct(meters.id)
FROM meters, meters_tags, houses_tags, tags
WHERE (
tags.name = "xxx" AND ((
meters_tags.tag_id = tags.id AND
meters_tags.meter_id = meters.id
)
)
);
これには 0.00 秒かかります。
SELECT distinct(meters.id)
FROM meters, meters_tags, houses_tags, tags
WHERE (
tags.name = "xxx" AND ((
houses_tags.tag_id = tags.id AND
houses_tags.house_id = meters.house_id
)
)
);
2 つのクエリのそれぞれに時間はかかりませんが、それらを OR すると 72 秒かかります。また、これを query0 AND ((query1) OR (query2)) の代わりに (query1) OR (query) の形式に変換しようとしましたが、これも非常に遅いです。
最初の(遅い)クエリの説明は次のとおりです。
+----+-------------+-------------+-------+----------------------------------------------------------------------------------------------------+------------------------------------------+---------+-------+-------+-------------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+-------+----------------------------------------------------------------------------------------------------+------------------------------------------+---------+-------+-------+-------------------------------------------------------+
| 1 | SIMPLE | meters_tags | index | index_meters_tags_on_tag_id_and_meter_id,index_meters_tags_on_tag_id,index_meters_tags_on_meter_id | index_meters_tags_on_tag_id_and_meter_id | 10 | NULL | 1 | Using index; Using temporary |
| 1 | SIMPLE | tags | ref | PRIMARY,tags_name | tags_name | 258 | const | 1 | Using where; Using index |
| 1 | SIMPLE | meters | index | PRIMARY,index_meters_on_house_id | index_meters_on_house_id | 5 | NULL | 45389 | Using index; Using join buffer |
| 1 | SIMPLE | houses_tags | index | index_houses_tags_on_tag_id_and_house_id | index_houses_tags_on_tag_id_and_house_id | 10 | NULL | 7158 | Using where; Using index; Distinct; Using join buffer |
+----+-------------+-------------+-------+----------------------------------------------------------------------------------------------------+------------------------------------------+---------+-------+-------+-------------------------------------------------------+
これらのテーブルはどれも 100k 行を超えません。これら 2 つのクエリを個別に実行すると非常に高速に実行できるのに、これら 2 つのクエリをマージするのに非常に長い時間がかかる可能性があるのは何でしょうか? サブクエリだけでもかなり高速なので、必要なすべてのインデックスが存在するようです。