在最近对我们网站的MySQL(v5.5)监控中,我们发现它经常会产生如此繁重的查询:
SELECT b.PRODUCT_ID, b1.PRODUCT_ID, 1 FROM b_sale_basket b, b_sale_basket b1
WHERE b.ORDER_ID = b1.ORDER_ID AND b.ORDER_ID = 15500 AND b.ID <> b1.ID AND
NOT EXISTS (SELECT 1 FROM b_sale_product2product d
WHERE d.PRODUCT_ID = b.PRODUCT_ID AND d.PARENT_PRODUCT_ID = b1.PRODUCT_ID);
它运行超过60秒。并返回12K行。
b_sale_product2product 有5100万条记录, b_sale_basket 有640条记录。
所有使用的字段都有受尊重的索引。只是找不到为什么这么痛苦的原因。
请帮忙。
表格结构:
CREATE TABLE `b_sale_product2product` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`PRODUCT_ID` int(11) NOT NULL,
`PARENT_PRODUCT_ID` int(11) NOT NULL,
`CNT` int(11) NOT NULL,
PRIMARY KEY (`ID`),
KEY `IXS_PRODUCT2PRODUCT_PRODUCT_ID` (`PRODUCT_ID`),
KEY `IXS_PRODUCT2PRODUCT_PARENT_AND_PRODUCT_ID` (`PRODUCT_ID`,`PARENT_PRODUCT_ID`),
KEY `IXS_PRODUCT2PRODUCT_PARENT_PRODUCT_ID` (`PARENT_PRODUCT_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=52036712 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
CREATE TABLE `b_sale_basket` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`FUSER_ID` int(11) NOT NULL,
`ORDER_ID` int(11) DEFAULT NULL,
`PRODUCT_ID` int(11) NOT NULL,
`PRODUCT_PRICE_ID` int(11) DEFAULT NULL,
`PRICE` decimal(18,2) NOT NULL,
`CURRENCY` char(3) COLLATE utf8_unicode_ci NOT NULL,
`DATE_INSERT` datetime NOT NULL,
`DATE_UPDATE` datetime NOT NULL,
`WEIGHT` double(18,2) DEFAULT NULL,
/* ... skipped ... */
PRIMARY KEY (`ID`),
KEY `IXS_BASKET_LID` (`LID`),
KEY `IXS_BASKET_USER_ID` (`FUSER_ID`),
KEY `IXS_BASKET_ORDER_ID` (`ORDER_ID`),
KEY `IXS_BASKET_PRODUCT_ID` (`PRODUCT_ID`),
KEY `IXS_BASKET_PRODUCT_PRICE_ID` (`PRODUCT_PRICE_ID`),
KEY `IXS_SBAS_XML_ID` (`PRODUCT_XML_ID`,`CATALOG_XML_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=962527 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
EXPLAIN结果:
+----+--------------------+-------+------+----------------------------------------------------------------------------------------------------------------+--------------------------------+---------+-------------------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+-------+------+----------------------------------------------------------------------------------------------------------------+--------------------------------+---------+-------------------------+------+-------------+
| 1 | PRIMARY | b | ref | IXS_BASKET_ORDER_ID | IXS_BASKET_ORDER_ID | 5 | const | 179 | Using where |
| 1 | PRIMARY | b1 | ref | IXS_BASKET_ORDER_ID | IXS_BASKET_ORDER_ID | 5 | const | 179 | Using where |
| 2 | DEPENDENT SUBQUERY | d | ref | IXS_PRODUCT2PRODUCT_PRODUCT_ID,IXS_PRODUCT2PRODUCT_PARENT_AND_PRODUCT_ID,IXS_PRODUCT2PRODUCT_PARENT_PRODUCT_ID | IXS_PRODUCT2PRODUCT_PRODUCT_ID | 4 | b.PRODUCT_ID | 1 | Using where |
+----+--------------------+-------+------+----------------------------------------------------------------------------------------------------------------+--------------------------------+---------+-------------------------+------+-------------+
答案 0 :(得分:0)
请尝试添加 -
Force index (IXS_PRODUCT2PRODUCT_PARENT_AND_PRODUCT_ID)
SELECT b.PRODUCT_ID, b1.PRODUCT_ID, 1 FROM b_sale_basket b, b_sale_basket b1
WHERE b.ORDER_ID = b1.ORDER_ID AND b.ORDER_ID = 15500 AND b.ID <> b1.ID AND
NOT EXISTS (SELECT 1
FROM b_sale_product2product d
Force index (IXS_PRODUCT2PRODUCT_PARENT_AND_PRODUCT_ID)
WHERE d.PRODUCT_ID = b.PRODUCT_ID AND d.PARENT_PRODUCT_ID = b1.PRODUCT_ID )
答案 1 :(得分:0)
align-items
看起来非常像许多:许多映射表,加上justify-content
。如果这是正确的,那么摆脱b_sale_product2product
,它只会减慢速度。并且未能发现对cnt
是唯一的。查看我的many:many tips。唉,这实际上并没有帮助你当前的查询;但它应该帮助其他人。
或ID
是一个层次结构,&#34; parent&#34;暗示?如果是这样,是否只有一个&#34;父母&#34;对于每个&#34;产品&#34;?如果是这种情况,查询应该可以简化。
您的查询从两个表之间的交叉连接开始,每个表大约有179行。接下来是p2p表中的32,041个查找。但该表中实际上只有179个有趣的行。
也就是说,如果你从179行(产品加上单亲)开始,那么只需要检查179件事,而不是179 * 179件。没有交叉加入。像这个订单的东西
product_id, parent_product_id
(我的大脑在试图弄清楚你的查询试图做什么时遇到了足够的麻烦;没有足够的脑力来为你写出这个查询。)