У меня эти таблицы в MySQL.Улучшение SQL в MySQL
CREATE TABLE `tableA` (
`id_a` int(11) NOT NULL,
`itemCode` varchar(50) NOT NULL,
`qtyOrdered` decimal(15,4) DEFAULT NULL,
:
PRIMARY KEY (`id_a`),
KEY `INDEX_A1` (`itemCode`)
) ENGINE=InnoDB
CREATE TABLE `tableB` (
`id_b` int(11) NOT NULL AUTO_INCREMENT,
`qtyDelivered` decimal(15,4) NOT NULL,
`id_a` int(11) DEFAULT NULL,
`opType` int(11) NOT NULL, -- '0' delivered to customer, '1' returned from customer
:
PRIMARY KEY (`id_b`),
KEY `INDEX_B1` (`id_a`)
KEY `INDEX_B2` (`opType`)
) ENGINE=InnoDB
tableA
показывает, сколько количества мы получили заказ от клиента, tableB
показывает, сколько количества мы поставили к клиенту для каждого заказа.
Я хочу сделать SQL, который подсчитывает количество оставшегося количества для доставки по каждому itemCode
. SQL выглядит следующим образом. Этот SQL работает, но медленный.
SELECT T1.itemCode,
SUM(IFNULL(T1.qtyOrdered,'0')-IFNULL(T2.qtyDelivered,'0')+IFNULL(T3.qtyReturned,'0')) as qty
FROM tableA AS T1
LEFT JOIN (SELECT id_a,SUM(qtyDelivered) as qtyDelivered FROM tableB WHERE opType = '0' GROUP BY id_a)
AS T2 on T1.id_a = T2.id_a
LEFT JOIN (SELECT id_a,SUM(qtyDelivered) as qtyReturned FROM tableB WHERE opType = '1' GROUP BY id_a)
AS T3 on T1.id_a = T3.id_a
WHERE T1.itemCode = '?'
GROUP BY T1.itemCode
Я попытался explain
на этом SQL, и результат, как показано ниже.
+----+-------------+------------+------+----------------+----------+---------+-------+-------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+------+----------------+----------+---------+-------+-------+----------------------------------------------+
| 1 | PRIMARY | T1 | ref | INDEX_A1 | INDEX_A1 | 152 | const | 1 | Using where |
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 21211 | |
| 1 | PRIMARY | <derived3> | ALL | NULL | NULL | NULL | NULL | 10 | |
| 3 | DERIVED | tableB | ref | INDEX_B2 | INDEX_B2 | 4 | | 96 | Using where; Using temporary; Using filesort |
| 2 | DERIVED | tableB | ref | INDEX_B2 | INDEX_B2 | 4 | | 55614 | Using where; Using temporary; Using filesort |
+----+-------------+-------------------+----------------+----------+---------+-------+-------+----------------------------------------------+
Я хочу улучшить свой запрос. Как я могу это сделать?
Я не думаю, что есть какая-либо точка в 'WHERE opType IN (0 , 1) ', поскольку это единственные два возможных значения. – Barmar
Спасибо за ответ. Но использование sub-запроса делает мой запрос медленным, я думаю. Я хочу исключить суб-запрос. Могу ли я сделать то же самое без подзапроса? –
@ N.F., Какой подзапрос. Даже ваш первоначальный образец показывает TWO-подзапросы, из которых я сводился к одному и учитывал обе части в одном. Второй образец, опять же, основывался на количестве ваших данных, элементах и запросил все независимо от элемента и присоединился к этому элементу. Вам нужно ПО ПОДРОБНОМУ 1 подзапрос, чтобы удалить ВОЗМОЖНЫЕ дублирования доставки/возврата. – DRapp