Wicked
Новичок
Подзапросы
Стал изучать сабж в свете возможности оптимизировать с помощью них запросы.
Оказалось, что они работают как-то не так, как я ожидал
Опишу на примере:
Есть таблица `ext_feeder_user_feed` подписок пользователей `feeder_id` на фиды `feed_id`. Всего ~9400 записей.
Есть таблица `ext_feeder_feed` фидов с PK `id`. Всего ~7400 фидов.
Пользователь X подписан на 346 фидов.
Сначала попытался выбрать детальную информацию о фидах с помощью такого запроса:
[sql]select `id`, `title` from `ext_feeder_feed` where `id` IN (
select `feed_id` from `ext_feeder_user_feed` where `feeder_id` = 70861
);[/sql]
И думал, что он сначала выполнит подзапрос (потому что он не зависит от внешних факторов), и будет использовать его результаты для выполнения внешнего запроса, грубо говоря, в таком виде:
[sql]select `id`, `title` from `ext_feeder_feed` where `id` IN (10, 49, 894, 1223, etc.)[/sql]
На практике же оказалось, что он действует наоборот: берет все фиды, и по очереди проверяет, не подписан ли юзер на какие-нибудь из них, т.е. делает фуллскан.
В то же время, я могу сделать запрос с обычным inner join-ом, и получить те же результаты с куда более вкусным explain'ом:
[sql]select `ext_feeder_feed`.`id`
from `ext_feeder_feed`
inner join `ext_feeder_user_feed` on (`ext_feeder_feed`.`id` = `ext_feeder_user_feed`.feed_id)
where `ext_feeder_user_feed`.`feeder_id` = 70861;[/sql]
Итого:
1) Что я делаю не так?
2) Как вообще можно использовать подзапросы для оптимизации?
Стал изучать сабж в свете возможности оптимизировать с помощью них запросы.
Оказалось, что они работают как-то не так, как я ожидал

Опишу на примере:
Есть таблица `ext_feeder_user_feed` подписок пользователей `feeder_id` на фиды `feed_id`. Всего ~9400 записей.
Есть таблица `ext_feeder_feed` фидов с PK `id`. Всего ~7400 фидов.
Пользователь X подписан на 346 фидов.
Сначала попытался выбрать детальную информацию о фидах с помощью такого запроса:
[sql]select `id`, `title` from `ext_feeder_feed` where `id` IN (
select `feed_id` from `ext_feeder_user_feed` where `feeder_id` = 70861
);[/sql]
И думал, что он сначала выполнит подзапрос (потому что он не зависит от внешних факторов), и будет использовать его результаты для выполнения внешнего запроса, грубо говоря, в таком виде:
[sql]select `id`, `title` from `ext_feeder_feed` where `id` IN (10, 49, 894, 1223, etc.)[/sql]
На практике же оказалось, что он действует наоборот: берет все фиды, и по очереди проверяет, не подписан ли юзер на какие-нибудь из них, т.е. делает фуллскан.
Код:
+----+--------------------+----------------------+----------------+----- -+-----------+---------+------+------+--------------------------+
| id | select_type | table | type | poss | key | key_len | ref | rows | Extra |
+----+--------------------+----------------------+----------------+----- -+-----------+---------+------+------+--------------------------+
| 1 | PRIMARY | ext_feeder_feed | index | NULL | state_idx | 4 | NULL | 7359 | Using where; Using index |
| 2 | DEPENDENT SUBQUERY | ext_feeder_user_feed | index_subquery | ext_ | feed_id | 8 | func | 1 | Using where |
+----+--------------------+----------------------+----------------+----- -+-----------+---------+------+------+--------------------------+
[sql]select `ext_feeder_feed`.`id`
from `ext_feeder_feed`
inner join `ext_feeder_user_feed` on (`ext_feeder_feed`.`id` = `ext_feeder_user_feed`.feed_id)
where `ext_feeder_user_feed`.`feeder_id` = 70861;[/sql]
Код:
+----+-------------+----------------------+--------+----- -+-----------+---------+--------- -+------+-------------+
| id | select_type | table | type | poss | key | key_len | ref | rows | Extra |
+----+-------------+----------------------+--------+----- -+-----------+---------+--------- -+------+-------------+
| 1 | SIMPLE | ext_feeder_user_feed | ref | ext_ | feeder_id | 8 | const | 345 | Using index |
| 1 | SIMPLE | ext_feeder_feed | eq_ref | PRIM | PRIMARY | 8 | kia_test | 1 | Using index |
+----+-------------+----------------------+--------+----- -+-----------+---------+--------- -+------+-------------+
1) Что я делаю не так?

2) Как вообще можно использовать подзапросы для оптимизации?