我有一个相关的子查询,执行需要 16 分钟。我如何转换它以加入或优化它。
SELECT SSF.SM_StockCode, SSF.ST_ItemSize FROM Stock AS SSF
WHERE SSF.SM_StockCode = (
SELECT SM_StockCode
FROM Stock AS SSFAI
WHERE SSFAI.ST_StockCode = SSF.ST_StockCode
ORDER BY SSFAI.ST_ItemSize ASC
LIMIT 1
) GROUP BY SSF.SM_StockCode
更新:添加了解释计划
+----+--------------------+-------+-------+-------------------+------------------+---------+------+-------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+-------+-------+-------------------+------------------+---------+------+-------+----------------------------------------------+
| 1 | PRIMARY | SSF | ALL | NULL | NULL | NULL | NULL | 45180 | Using where; Using temporary; Using filesort |
| 2 | DEPENDENT SUBQUERY | SSFAI | index | ST_StockCode_Indx | ST_ItemSize_Indx | 9 | NULL | 1 | Using where |
+----+--------------------+-------+-------+-------------------+------------------+---------+------+-------+----------------------------------------------+
更新:表结构
CREATE TABLE `Stock` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`ST_StockCode` varchar(20) NOT NULL,
`SM_StockCode` varchar(20) NOT NULL,
`ST_ItemSize` decimal(18,2) NOT NULL,
PRIMARY KEY (`id`),
KEY `ST_StockCode_Indx` (`ST_StockCode`),
KEY `SM_StockCode_Indx` (`SM_StockCode`),
KEY `ST_ItemSize_Indx` (`ST_ItemSize`)
) ENGINE=MyISAM;
你有
SELECT SSF.ST_ItemSize
afterGROUP BY SSF.SM_StockCode
,所以你在列表中使用没有聚合的SELECT
列,一个不在列表中的GROUP BY
列。根据 1992 标准,这不是有效的 SQL。
由于
ST_ItemSize
既不是主键也没有唯一约束,因此在ST_ItemSize
功能上不依赖于它。这使得 SQL 代码即使在 2003+ 版本中也不符合 ISO/ANSI 标准,并且会给出不确定的结果(在ST_ItemSize
列中)。不幸的是,MySQL 允许这样的查询(不进行依赖性检查)并且开发人员有责任确保查询将给出确定的结果。
所以我建议从你的代码中删除这个查询,与编写它的开发人员或使用它的开发人员讨论并找出它应该返回什么结果。然后你可以重写它。
如果你仍然想让它运行直到你这样做,以下将产生类似的结果 - 并将通过索引提高效率
(ST_StockCode, ST_ItemSize, SM_StockCode)
:很难说出您要做什么;什么是
SM_StockCode
和ST_StockCode
?这是我的第一次重写:不过,看起来您需要的可能就这么简单:
如果你给我们一些样本数据,我会更有信心。