Скорее всего, он медленный, потому что он выполняет коррелированный подзапрос для каждой строки внешнего запроса.Есть два решения, которые имеют тенденцию работать более эффективно.
Одним из них является использование производной таблицы , которая использует подзапрос, но выполняет подзапрос только один раз для подготовки производной таблицы.
SELECT B.RECORDID, A.ITEMCODE, A.ITEMNAME, A.STOCKINHAND, B.SALEPRICE
FROM ITEMMASTER A
JOIN STOCKENTRY B ON A.ITEMID = B.ITEMID
JOIN (SELECT ITEMID, MAX(RECORDID) AS MAXRECORDID
FROM STOCKENTRY GROUP BY ITEMID) M
ON (M.ITEMID, M.MAXRECORDID) = (B.ITEMID, B.RECORDID)
WHERE A.STOCKINHAND > 0
AND B.SALEPRICE > 0
AND B.INVOICEDATE IS NOT NULL
ORDER BY A.ITEMNAME, B.INVOICEDATE;
Другое решение состоит в том, чтобы использовать исключающее соединение , чтобы найти строку в B так, чтобы не было другой строки с таким же itemid и большим значением recordid.При правильных индексах (например, составной индекс (ITEMID, RECORDID) это должно работать очень хорошо.
SELECT B.RECORDID, A.ITEMCODE, A.ITEMNAME, A.STOCKINHAND, B.SALEPRICE
FROM ITEMMASTER A
JOIN STOCKENTRY B ON A.ITEMID = B.ITEMID
LEFT OUTER JOIN STOCKENTRY B2
ON B.ITEMID = B2.ITEMID AND B.RECORDID < B2.RECORDID
WHERE B2.ITEMID IS NULL
AND A.STOCKINHAND > 0
AND B.SALEPRICE > 0
AND B.INVOICEDATE IS NOT NULL
ORDER BY A.ITEMNAME, B.INVOICEDATE;
Этот тип проблем часто возникает при переполнении стека. Я добавил наибольшее-n-per-group тег к вопросу, чтобы вы могли видеть другие случаи.
Комментарий Re @ RPK:
Я сам не использую MySQL QB, иэто приложение менялось так много раз, что я не могу посоветовать, как его использовать, но в мониторе mysql (командной строке) я использую комбинацию EXPLAIN и PROFILING длядайте мне статистику.
Тем не менее, вы сделали комментарий о том, что не нужно изменять (или создавать?) индексы. Это помешает вашим попыткам оптимизировать.