Вы можете использовать декларативный модуль для списков данных, таких как query-js (*). В этих ситуациях я лично считаю декларативный подход менее неожиданным
var funcs = Query.range(0,3).each(function(i){
return function() {
console.log("My value: " + i);
};
});
. Затем вы можете использовать свой второй цикл и получить ожидаемый результат, или вы могли бы сделать
funcs.iterate(function(f){ f(); });
(*) Я автор запросов-js и поэтому склонен к его использованию, поэтому не принимайте мои слова в качестве рекомендации для указанной библиотеки только для декларативного подхода:)
Для целей оптимизации хорошим правилом является объединение меньше, а не больше. На самом деле, вы должны попытаться объединить несколько строк, сколько сможете, с минимальным количеством строк. При любом дополнительном соединении вы будете умножать стоимость, а не увеличивать стоимость. Поскольку mysql будет просто генерировать большую умноженную матрицу.
Но ответить на ваш вопрос: на самом деле можно рассчитывать только с одним большим соединением, предполагая, что таблицы имеют уникальные ключи, а idalb - уникальное ключ для альбома. Затем, и только тогда вы можете сделать это аналогично вашему коду:
select alb.titreAlb as "Titre",
count(distinct payalb.idAlb, payalb.PrimaryKeyFields) "Pays",
count(distinct peralb.idAlb, peralb.PrimaryKeyFields) "Personnages",
count(distinct juralb.idAlb, juralb.PrimaryKeyFields) "Jurons"
from album alb
left join pays_album payalb using ( idAlb )
left join pers_album peralb using ( idAlb )
left join juron_album juralb using ( idAlb )
where alb.titreAlb = "LES CIGARES DU PHARAON"
group by alb.titreAlb
, где PrimaryKeyFields обозначает поля первичного ключа объединенных таблиц (вы должны искать их).
Distinct
удалит эффект, который другие соединения имеют в счетчике. Но, к сожалению, в общем случае distinct
не удалит эффект, который имеют соединения, связанные с затратами.
Хотя, если у вас есть индексы, которые покрывают все поля (idAlb + PrimaryKeyFields) ваших таблиц, это может быть настолько же быстрым, как исходное решение (потому что он может оптимизировать distinct
, чтобы не сортировать) и приблизится к тому, о чем вы думали (просто пройдите через каждый стол / индекс один раз). Но в нормальном или худшем случае szenario он должен выполнять хуже, чем разумное решение (например, SlimGhost), потому что вряд ли он найдет оптимальную стратегию. Но поиграйте с ним и проверьте объяснения (и опубликуйте результаты), возможно, mysql сделает что-то безумное.
Что касается «наименее эффективной работы для db», я думаю, что следующее было бы правильным и менее логичным вводом-выводом для вашей схемы. Поймите, однако, что вы НЕ МОЖЕТЕ знать наверняка, если не посмотрите на планы объяснения (ожидаемые и фактические).
Тем не менее, я рекомендую попробовать это - он обращается к таблице «alb» только один раз, тогда как ваш исходный запрос необходимо будет получить к нему доступ четыре раза (один раз, чтобы получить «базовую» запись альбома, а затем еще три для трех подзапросов).
select alb.titreAlb as "Titre",
(select count(*) from pays_album t2 where t2.idAlb = alb.idAlb) "Pays",
(select count(*) from pers_album t2 where t2.idAlb = alb.idAlb) "Personnages",
(select count(*) from juron_album t2 where t2.idAlb = alb.idAlb) "Jurons"
from album alb
where alb.titreAlb = "LES CIGARES DU PHARAON"