Если мы хотим придерживаться коррелированных подзапросов, мы можем исключить встроенное представление p
.
Это будет реализовано для каждой строки, извлеченной из Sales
.Предикат в предложении WHERE
во внешнем запросе не «выталкивается» в представление.Таким образом, материализованное представление (или «производная таблица» на языке MySQL) будет полным набором, и из этого мы выделим всего несколько строк.И мы собираемся повторить это для каждой строки из Sales
.
Разматывание этой производной таблицы должно дать нам некоторое повышение производительности.Это было бы разумным подходом для небольшого числа строк, возвращаемых из Sales
, с определением подходящих индексов.То есть, если бы мы ограничивали количество строк, проверяемых внешним запросом, с помощью предложения WHERE
.При большом количестве строк эти коррелированные подзапросы снизят производительность.
SELECT ( SELECT c.name
FROM Customers c
WHERE c.id = s.customer_id
) AS customer
, ( SELECT GROUP_CONCAT(CONCAT('x',si.Qty,' ',p.name,' ',si.total) ORDER BY p.name SEPARATOR '\r\n')
FROM Sale_Items si
LEFT
JOIN Products p
ON p.id = si.product_id
WHERE si.sale_id = s.id
) AS detail
, s.total
FROM Sales s
WHERE ...
ORDER
BY ...
Если запрос возвращает все строки из Sales
и мы выполняем весь набор bloomin 'set, то I'Я стараюсь избегать коррелированных подзапросов.(Это потому, что подзапросы выполняются для каждой строки, возвращаемой внешним запросом. Эти подзапросы будут съедать наш обед с точки зрения производительности с большим количеством возвращаемых строк.)
Предполагая id
уникален в customers
, нам, как правило, гораздо лучше с операцией соединения.
SELECT c.name AS customer
, d.detail
, s.total
FROM Sales s
LEFT
JOIN Customers c
ON c.id = s.customer_id
LEFT
JOIN ( SELECT si.sale_id
, GROUP_CONCAT(CONCAT('x',si.Qty,' ',p.name,' ',si.total) ORDER BY p.name SEPARATOR '\r\n') AS detail
FROM Sale_Items si
LEFT
JOIN Products p
ON p.id = si.product_id
GROUP
BY si.sale_id
) d
ON d.sale_id = s.id
ORDER
BY ...
Встроенное представление d
будет дорого с большими наборами;но, по крайней мере, мы делаем этот запрос только один раз, материализуя результаты в «производную таблицу».Затем можно выполнить внешний запрос и извлечь строки из производной таблицы.