Допустим, у меня есть следующая гипотетическая структура данных:
create table "country"
(
country_id integer,
country_name varchar(50),
continent varchar(50),
constraint country_pkey primary key (country_id)
);
create table "person"
(
person_id integer,
person_name varchar(100),
country_id integer,
constraint person_pkey primary key (person_id)
);
create table "event"
(
event_id integer,
event_desc varchar(100),
country_id integer,
constraint event_pkey primary key (event_id)
);
Я хочу запросить количество строк людей и событий в каждой стране.Я решил использовать подзапрос.
select c.country_name, sum(sub1.person_count) as person_count, sum(sub2.event_count) as event_count
from
"country" c
left join (select country_id, count(*) as person_count from "person" group by country_id) sub1
on (c.country_id=sub1.country_id)
left join (select country_id, count(*) as event_count from "event" group by country_id) sub2
on (c.country_id=sub2.country_id)
group by c.country_name
Я знаю, что вы можете сделать это, используя операторы select в списке полей, но преимущество использования подзапросов состоит в том, что я более гибок в изменении SQL, чтобы сделать его обобщенным и использовать другое поле.Допустим, если я изменю запрос для отображения его по континентам, это будет так же просто, как заменить поле «c.country_name» на «c.continent».
Моя проблема связана с фильтрацией.Если мы добавим предложение where следующим образом:
select c.country_name,
sum(sub1.person_count) as person_count,
sum(sub2.event_count) as event_count
from
"country" c
left join (select country_id, count(*) as person_count from "person" group by country_id) sub1
on (c.country_id=sub1.country_id)
left join (select country_id, count(*) as event_count from "event" group by country_id) sub2
on (c.country_id=sub2.country_id)
where c.country_name='UNITED STATES'
group by c.country_name
Кажется, что подзапросы все еще выполняют подсчет для всех стран.Предположим, что таблицы person и event огромны, и у меня уже есть индексы country_id для всех таблиц.Это действительно медленно.Разве база данных не должна выполнять только подзапросы для страны, которая была отфильтрована?Нужно ли заново создавать фильтр страны для каждого подзапроса (это очень утомительно и код не легко изменить)?Кстати, я использую PostgreSQL 8.3 и 9.0, но я думаю, что то же самое происходит и в других базах данных.