【问题标题】:MySQL query optimization and performanceMySQL 查询优化和性能
【发布时间】:2015-09-04 20:05:21
【问题描述】:

我的表结构如下:

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" = "n"的最佳方法是什么?

【问题讨论】:

  • 这个问题在 SO 上已经被问了很多次(糟糕地)。它不是重复的,因为答案通常不同。但是,如果您阅读之前的一些问题和评论,您会发现如果不至少提供 EXPLAIN 计划和表格结构,就无法回答这个问题。
  • 感谢 symcbean 的回复。相信,我检查了几个线程,但没有找到我的问题的答案!也许你骗我指向其中的一些!
    表结构正是我给出的,但没有所有列时稍微简化了...
  • 请为每张桌子提供SHOW CREATE TABLE
  • 嗨 Rick,我已经更新了我的初始消息。谢谢
  • @Websphere 请提供您的实际查询,而不是...WHERE CONDITION。这些细节对于与性能相关的问题极为重要。您选择或过滤的每一列都会对性能产生影响。另外,请修正表定义以实际显示SHOW CREATE TABLE product_vars 的结果。该语句中的 PRIMARY KEY 列甚至不存在于您的表中。

标签: mysql query-optimization inner-join query-performance


【解决方案1】:

嗯,这是目前对我有用的查询:

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),然后最后出现不可用的产品?

谢谢

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-07-26
    • 1970-01-01
    • 2018-06-21
    • 2022-10-13
    • 2022-11-19
    • 1970-01-01
    • 2021-12-06
    • 2016-12-01
    相关资源
    最近更新 更多