MySQL忽略了索引问题

时间:2016-11-28 10:42:54

标签: mysql sql performance indexing

在最近对我们网站的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 |
+----+--------------------+-------+------+----------------------------------------------------------------------------------------------------------------+--------------------------------+---------+-------------------------+------+-------------+

2 个答案:

答案 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

(我的大脑在试图弄清楚你的查询试图做什么时遇到了足够的麻烦;没有足够的脑力来为你写出这个查询。)