SQL Query, кажется, умножает результаты? [Дубликат]

Вы можете использовать декларативный модуль для списков данных, таких как query-js (*). В этих ситуациях я лично считаю декларативный подход менее неожиданным

var funcs = Query.range(0,3).each(function(i){
     return  function() {
        console.log("My value: " + i);
    };
});

. Затем вы можете использовать свой второй цикл и получить ожидаемый результат, или вы могли бы сделать

funcs.iterate(function(f){ f(); });

(*) Я автор запросов-js и поэтому склонен к его использованию, поэтому не принимайте мои слова в качестве рекомендации для указанной библиотеки только для декларативного подхода:)

1
задан Adrien Horgnies 25 May 2016 в 13:00
поделиться

2 ответа

Для целей оптимизации хорошим правилом является объединение меньше, а не больше. На самом деле, вы должны попытаться объединить несколько строк, сколько сможете, с минимальным количеством строк. При любом дополнительном соединении вы будете умножать стоимость, а не увеличивать стоимость. Поскольку 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 сделает что-то безумное.

2
ответ дан Solarflare 22 August 2018 в 21:28
поделиться

Что касается «наименее эффективной работы для 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"
1
ответ дан SlimsGhost 22 August 2018 в 21:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: