首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在MySQL中优化Max(Date)查询

如何在MySQL中优化Max(Date)查询
EN

Stack Overflow用户
提问于 2019-10-24 22:04:42
回答 2查看 339关注 0票数 1

我有一个SQL查询:

代码语言:javascript
运行
复制
SELECT company.*, salesorder.lastOrderDate
FROM company
INNER JOIN 
(
SELECT companyId, MAX(orderDate) AS lastOrderDate 
FROM salesorder
GROUP BY companyId
) salesorder ON salesorder.companyId = company.companyId;

这使我在公司主表的末尾多了一列,显示了他们的最后订单日期。

问题是,当分析这个查询时,它似乎没有那么高效:

有没有办法让它更有效率呢?

代码语言:javascript
运行
复制
salesorder:

orderId, companyId, orderDate
1          333      2015-01-01
2          555      2016-01-01
3          333      2017-01-01


company

companyId, name
333        Acme
555        Microsoft


Query:

companyId, name,       lastOrderDate
333        Acme        2017-01-01
555        Microsoft   2016-01-01

解释SELECT:

代码语言:javascript
运行
复制
CREATE TABLE `salesorder` (
  `orderId` int(11) NOT NULL,
  `companyId` int(11) DEFAULT NULL,
  `orderDate` date DEFAULT NULL,
  PRIMARY KEY (`orderId`),
  UNIQUE KEY `orderId_UNIQUE` (`orderId`) /*!80000 INVISIBLE */,
  KEY `testComposite` (`companyId`,`orderDate`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

CREATE TABLE `company` (
  `companyId` int(11) NOT NULL,
  `name` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`companyId`),
  UNIQUE KEY `companyId_UNIQUE` (`companyId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
EN

回答 2

Stack Overflow用户

发布于 2019-12-26 23:35:10

按以下顺序添加包含列的复合索引:

代码语言:javascript
运行
复制
INDEX(companyId, orderDate)

单列索引效率不高(在此查询中)。

因为PRIMARY KEY是唯一的密钥,所以不要多余地声明UNIQUE密钥。

由于表中只有几行,您不能相信EXPLAIN (以及类似解释的输出)来判断查询会有多糟糕。尝试使用至少几十行。并提供EXPLAIN FORMAT=JSON SELECT ...

注意,上面写着“使用索引”。也就是说,所讨论的子查询可以完全在索引的BTree中执行。这是“好的”。(我假设您在添加了我建议的索引之后执行了EXPLAIN?)

您之前的图像显示了很多行;这说明了什么?

我仍然不明白为什么EXPLAIN中有3行和两个表扫描。无论如何,下面是另一个可以尝试的公式:

代码语言:javascript
运行
复制
SELECT  c.*,
        ( SELECT MAX(orderDate)
              FROM salesorder
              WHERE companyId = c.companyId
        ) AS lastOrderDate
    FROM  company AS c;

(我的INDEX仍然很重要)

票数 1
EN

Stack Overflow用户

发布于 2020-01-06 09:52:11

看起来您可以像这样简化查询:

代码语言:javascript
运行
复制
SELECT c.*, MAX(o.OrderDate) As lastOrderDate
FROM company c
INNER JOIN salesorder o on o.companyId = c.companyId
GROUP BY <list all company fields here>;

MySql甚至可以让您在GROUP BY子句中只使用c.companyId,但这不是真正的标准,也不是很好的实践。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58543135

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档