2015-09-04 3 views
0

Уважаемые члены StackOverflow,оптимизация запросов MySQL и производительность

У меня есть следующая структура таблицы:

CREATE TABLE IF NOT EXISTS `products` (
`id_product` int(10) unsigned NOT NULL AUTO_INCREMENT, 
`name` varchar(60) COLLATE utf8_unicode_ci NOT NULL, 
PRIMARY KEY (`id_product`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ; 

CREATE TABLE IF NOT EXISTS `products_vars` (
`id_product` int(10) unsigned NOT NULL, 
`id_product_var` int(10) unsigned NOT NULL AUTO_INCREMENT, 
`price` decimal(7,2) NOT NULL, 
`discount` tinyint(3) unsigned NOT NULL DEFAULT '0', 
`stock` smallint(6) NOT NULL DEFAULT '0', 
`coming_soon` enum('y','n') COLLATE utf8_unicode_ci NOT NULL DEFAULT 'n', 
`date_add` datetime DEFAULT NULL, 
`date_update` datetime DEFAULT NULL, 
`active` enum('y','n') COLLATE utf8_unicode_ci NOT NULL DEFAULT 'n', 
PRIMARY KEY (`id_product_var`), 
KEY `id_product` (`id_product`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; 

ALTER TABLE `products_vars` 
ADD CONSTRAINT `products_vars_ibfk_1` FOREIGN KEY (`id_product`) REFERENCES `products` (`id_product`) ON DELETE CASCADE ON UPDATE CASCADE; 

Мне нужно, чтобы получить самый дешевый продукт с правильным ID, сильфон запрос работает хорошо, но я думаю, это немного медленно, поэтому мне было интересно, есть ли другой способ сделать это.

SELECT p.id_product, pv.coming_soon, pv.date_add, pv.price * (1 - (pv.discount/100)) AS price, MAX(pv.stock) AS stock, MAX(pv.date_add) AS date_add 
FROM products AS p 
INNER JOIN products_vars AS pv USING(id_product) 
INNER JOIN (SELECT pv.id_product, MIN(pv.price * (1 - (pv.discount/100))) AS min_price 
    FROM products_vars AS pv 
    WHERE pv.active = 'y' 
    GROUP BY pv.id_product) AS pv2 
    ON pv2.id_product = pv.id_product 
     AND min_price = pv.price * (1 - (pv.discount/100)) 
WHERE pv.active = 'y' 
GROUP BY pv.id_product 

И одна последняя вещь, пожалуйста: таблица «products_vars» может содержать несколько вариацию продукта (цвета или размеров), что это лучший способ сказать, если хотя бы один из них имеет «coming_soon» = «п "?

Большое спасибо за вашу помощь С уважением

+0

Этот вопрос задан (плохо) много раз здесь, на SO. Это не дубликат, так как ответ часто отличается. Но если вы прочитаете некоторые из предыдущих вопросов и КОММЕНТАРИИ, вы увидите, что на этот вопрос не может быть дан ответ, хотя бы не предоставляя планы EXPLAIN и структуры таблиц. – symcbean

+0

Спасибо symcbean за ваш ответ. Поверьте, я проверил несколько потоков, но не нашел ответа на мои вопросы! возможно, вы укажете мне на некоторые из них!
Структура таблицы точно такая, которую я дал, но немного упрощен без всех столбцов ... – Websphere

+0

Пожалуйста, предоставьте 'SHOW CREATE TABLE' для каждой таблицы. –

ответ

0

Ну, вот запрос, который работает для меня на данный момент:

SELECT 
    p.id_product, 
    pv.coming_soon, 
    pv.date_add, 
    pv.price * (1 - (pv.discount/100)) AS price, 
    MAX(pv.stock) AS stock, 
    MAX(pv.date_add) AS date_add, 
    (SELECT pv2.coming_soon FROM products_vars AS pv2 WHERE pv2.id_product = p.id_product AND pv2.coming_soon = 'n' LIMIT 1) AS coming_soon 
FROM products AS p 
INNER JOIN products_vars AS pv USING(id_product) 
INNER JOIN (SELECT pv.id_product, MIN(pv.price * (1 - (pv.discount/100))) AS min_price 
    FROM products_vars AS pv 
    WHERE pv.active = 'y' 
    GROUP BY pv.id_product) AS pv2 
    ON pv2.id_product = pv.id_product 
     AND min_price = pv.price * (1 - (pv.discount/100)) 
WHERE pv.active = 'y' 
GROUP BY pv.id_product 
ORDER BY stock DESC 

Это работает прекрасно, но я интересно, если:
1 - он оптимизирован
2- как сортировать товары по названию, но только для имеющихся (запас> 0), то наконец-то недоступны продукты?

Спасибо

Смежные вопросы