mysql - 为什么 MySQL 会更改不同数据库中查询的联接类型
问题描述
我们有不同的 RDS(AWS、GCP 等),这些 RDS 有很多数据库。我们的每个数据库都由相同的后端代码构建和管理,因此所有表和数据集都匹配。
我有一个查询,当我专门在一个数据库上运行时,它会停止运行,并且比较解释表明它正在被不同地对待。
所以对于这个例子,我有 first_table,这个 FK 是 second_table。所有索引等都正确形成。现在假设我们的 AWS RDS 上有 db_one,我们的 GCP 数据库服务器上有 db_two 和 db_three。
db_one 上的 first_table 为 2gb,db_two 为 8.8gb,db_three 为 20mb。我们要对其进行 FK 处理的 second_table 只有 64kb。
select * from first_table a
where first_table a.my_date between '2020-12-01 00:00:00' and '2020-12-01 00:00:00';
如果我在每个数据库上运行它,查询需要不到一秒钟的时间来运行和返回。在 db_two 上,由于大小的原因,通过网络将数据传输给我需要几秒钟的额外时间 - 这很好,也是意料之中的。
当我运行explain
它时,它显示“类型:范围,表:a”。这在所有数据库中都是一致的。
现在,当我添加 FK 连接并在 db_one 上运行时。就像瞬间一样。
select * from first_table a
join second_table b on b.ft_id = a.id
where first_table a.my_date between '2020-12-01 00:00:00' and '2020-12-01 00:00:00';
但是,当我在 db_two (最大的)上运行它时,它永远不会完成。
现在,当我在两个数据库上运行解释时,它们是不同的。
在 db_one 上,它仍然使用“类型:范围,表:a”和“类型:eq_ref,表:b”
现在在 db_two 上显示:“表:b,类型:ALL,表:a,类型:ref”
所以我认为这些 RDS 之间可能存在差异,或者其他什么,所以我在 db_three(与 db_two 位于同一台服务器上)上运行查询和解释,它立即运行并且解释与 db_one 上的相同。
事实上,我在不同数据库上对我们所有的 RDS 进行了解释,这始终是我所期望的:“表:a,类型:范围。表:b,类型:eq_ref”。
只有在具有最大表的 db_two 上,解释有所不同,但性能也很差。
谁能帮助解释为什么会这样?或者是什么原因造成的,我可以解决它吗?
我目前的解决方法就是跑快单表sql,然后返回python,然后拉取FK数据,自己手动拼接排序。至少那会运行。
但这似乎很疯狂。
希望我想念这里的一些东西。
解决方案
推荐阅读
- flutter - Flutter 正确构建 TabBarView 子项
- docker - 我在哪里可以找到 docker 上的 portainer.io 日志?
- python - 遇到错误后如何在python上重新运行代码?
- python - 保存到文本文件时防止分割线
- java - 我需要帮助来实现特定的休眠继承映射
- c++ - boost::asio 如何从客户端发送字符串数据并将其存储在服务器端进行处理
- php - laravel 单元测试错误'在 null 上调用成员函数 call()'
- c# - 为什么增加 iText7 跨跨单元格中的图像大小会意外改变我的列宽?
- centos - /usr/bin/yum: /usr/bin/python: 错误的解释器: 权限被拒绝
- python - 使用数据集的 matplotlib 绘制箱线图