首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如果没有返回结果,MySQL连接表查询返回需要很长时间。

如果没有返回结果,MySQL连接表查询返回需要很长时间。
EN

Stack Overflow用户
提问于 2022-01-24 05:21:40
回答 1查看 33关注 0票数 0

我有两个表,名为host_orderhost_order_line,作为1-n关系。我希望在这些表上找到最近的更新记录,并使用此查询。

代码语言:javascript
运行
复制
SELECT DISTINCT
    ho.id
FROM
    host_order ho
    JOIN host_order_line hol ON hol.host_order_id = ho.id 
        WHERE ho.last_modified_date > '2022-01-01'
        OR hol.last_modified_date > '2022-01-01'
    LIMIT 100;

我在两个表中都添加了last_modified_date索引,所以查询非常快。但是,如果更改结果为空的查询参数,则会突然慢下来。例如

代码语言:javascript
运行
复制
SELECT DISTINCT
    ho.id
FROM
    host_order ho
    JOIN host_order_line hol ON hol.host_order_id = ho.id
        WHERE ho.last_modified_date > '2023-01-01'
        OR hol.last_modified_date > '2023-01-01'
    LIMIT 100;

第一个查询大约需要7ms,但是第二个查询超过1秒。

我不确定主要问题是什么,以及如何解决查询性能。

-更新-我在这里添加了sql创建这些表

代码语言:javascript
运行
复制
CREATE TABLE `host_order` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `last_modified_date` datetime NOT NULL,
  PRIMARY KEY (`id`),
  KEY `last_modified_date` (`last_modified_date`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=12267 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

CREATE TABLE `host_order_line` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `host_order_id` bigint NOT NULL,
  `last_modified_date` datetime NOT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_last_modified_date` (`last_modified_date`) USING BTREE,
  KEY `host_order_id` (`host_order_id`) USING BTREE,
  CONSTRAINT `host_order_line_ibfk_1` FOREIGN KEY (`host_order_id`) REFERENCES `host_order` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=244811 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
EN

回答 1

Stack Overflow用户

发布于 2022-01-24 17:53:23

  • 你也许可以摆脱DISTINCT。它要求所有的结果在LIMITing之前被收集和去复制到100.

  • 也许你需要一个ORDER BY?没有它,您就无法预测将交付哪100行。

  • 这两个查询仅在日期范围上不同?那么要处理的数据量是不同的。这甚至可能影响查询计划。请为每个人提供EXPLAIN SELECT ...

  • ,但主要问题是OR。它不能很好地优化。转换为UNION可能是解决方案:

(选择ho.id从host_order ho.id host_order_line ho ON hol.host_order_id =ho.id,其中ho.last_modified_date > '2022-01-01‘按.(限制100 ) UNION DISTINCT ( ho.id FROM host_order ho JOIN host_order_line hol hol.host_order_id = ho.id,其中hol.last_modified_date > '2022-01-01‘按.限制100 )命令由.极限100;

是的,ORDER BY (如果需要的话)和LIMIT是重复的。这一提法将需要一些指数变化:

代码语言:javascript
运行
复制
ho:   INDEX(last_modified_date)

还有..。

它闻起来像host_order_line是一个多到多的映射表。在本例中,将PRIMARY KEY(id)和两个当前索引替换为以下两个:

代码语言:javascript
运行
复制
PRIMARY KEY(host_order_id, last_modified_date)
INDEX(last_modified_date, host_order_id)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70829330

复制
相关文章

相似问题

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