【问题标题】:MySQL LIMIT optimization issueMySQL LIMIT 优化问题
【发布时间】:2011-08-12 02:16:40
【问题描述】:

我有以下 MySQL 查询,我希望 LIMIT 更快,因为它的运行速度非常慢。 SQL_CALC_FOUND_ROWS 大约等于 114000 行。

SELECT SQL_CALC_FOUND_ROWS PStD.ProductID FROM ProductStoreDef PStD
    JOIN ProductSummary PS ON PStD.ProductID = PS.ProductID 
    JOIN MasterVendor MV ON MV.VendorID = PStD.MasterVendorID 
WHERE 
    PStD.SKUStatus = 'A' AND 
    MV.isActive = 1 AND 
    PStD.MasterCategoryID = 66 AND 
    PStD.CustomerPrice > 0
ORDER BY PStD.VendorName, PS.VendorPartNumber 
LIMIT 100000,50

以下是EXPLAIN结果

+----+-------------+-------+--------+-------------------------------------------------------------------------------------------------+-----------------+---------+-------------------------+------+----------------------------------------------+
| id | select_type | table | type   | possible_keys                                                                                   | key             | key_len | ref                     | rows | Extra                                        |
+----+-------------+-------+--------+-------------------------------------------------------------------------------------------------+-----------------+---------+-------------------------+------+----------------------------------------------+
|  1 | SIMPLE      | MV    | ALL    | PRIMARY,isActive,VendorID                                                                       | NULL            | NULL    | NULL                    | 2126 | Using where; Using temporary; Using filesort | 
|  1 | SIMPLE      | PStD  | ref    | PRIMARY,MasterVendorID,MasterCategoryID,SKUStatus,CustomerPrice,MasterVendCatID,ProdStoreStatus | MasterVendCatID | 8       | ecomm.MV.VendorID,const |   94 | Using where                                  | 
|  1 | SIMPLE      | PS    | eq_ref | PRIMARY                                                                                         | PRIMARY         | 4       | ecomm.PStD.ProductID    |    1 |                                              | 
+----+-------------+-------+--------+-------------------------------------------------------------------------------------------------+-----------------+---------+-------------------------+------+----------------------------------------------+

任何建议将不胜感激。

更新:通过创建一个单独的表格解决了这个问题,该表格预先计算了排序顺序,使网站的运行速度提高了大约 500 到 1000 倍。

【问题讨论】:

  • 您在 ProductStoreDef.VendorName 和 ProductSummary.VendorPartNumber 列上有索引吗?
  • 尽可能删除 SQL_CALC_FOUND_ROWS,它会大大减慢查询速度。并请显示 EXPLAIN 以供查询
  • 使用或不使用 SQL_CALC_FOUND_ROWS 绝对没有区别。 EXPLAIN 看起来一样。
  • @wonk0 在这种情况下它不应该减慢查询速度,因为尽管 SQL_CALC_FOUND_ROWS 查询应该处理所有行。

标签: mysql database optimization limit


【解决方案1】:

似乎问题在于排序。在这种情况下,您可以尝试创建这些索引,但我无法保证:

ALTER TABLE `ProductStoreDef` ADD INDEX `ProductStoreDef_CIndex` (
    `ProductID` ASC, `MasterVendorID` ASC, `MasterCategoryID` ASC, 
    `SKUStatus` ASC, `CustomerPrice` ASC, `VendorName` ASC
);    
ALTER TABLE `ProductSummary` ADD INDEX `ProductSummary_CIndex` (
    `ProductID` ASC, `VendorPartNumber` ASC
);    
ALTER TABLE `MasterVendor` ADD INDEX `MasterVendor_CIndex` (
    `VendorID` ASC, `isActive` ASC
);

【讨论】:

  • 如果这没有帮助,那么在您创建这些索引后再次给我一个 EXPLAIN 您的查询。
  • ProductStoreDef 索引:PRIMARY KEY (ProductID,StoreID), KEY MasterVendorID (MasterVendorID), KEY MasterCategoryID (MasterCategoryID), KEY LastUpdate (LastUpdate), KEY SKUStatus (SKUStatus), KEY CustomerPrice (CustomerPrice), KEY VendorName (VendorName), KEY MasterVendCatID (MasterVendorID,MasterCategoryID), KEY ProdStoreStatus (ProductID,StoreID,SKUStatus), KEY StoreCat (StoreID,MasterCategoryID,CustomerPrice,SKUStatus), KEY StoreLastUpdate (StoreID,LastUpdate), KEY StoreID_2 (StoreID,MasterVendorID, MasterCategoryID,CustomerPrice,SKUStatus)
  • ProductSummary Indexes: PRIMARY KEY (ProductID), KEY VendorPartNumber (VendorPartNumber), KEY Quantity (Quantity) MasterVendor Indexes: PRIMARY KEY (VendorID), KEY isActive (isActive), KEY LastUpdate (LastUpdate), KEY Vendor(供应商),KEY VendorActive(VendorID,isActive)
  • @Jesse 没关系,你有我提到的索引之一。现在让我们创建前两个 :)
  • @Jesse 问题是你提到的索引都没有帮助排序。是的,您对 VendorName 和 VendorPartNumber 有单独的索引,但它们在过滤过程之后不能使用。所以你需要将它们包含在复合索引中(就像我的回答一样)。注意:顺序很重要。
猜你喜欢
  • 2010-10-20
  • 1970-01-01
  • 2015-07-28
  • 1970-01-01
  • 1970-01-01
  • 2011-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多