mysql - mysql索引在rails中行为不端
问题描述
我有一个使用 Mysql 托管的 Rails 应用程序,在rescheduled_reservation_id列(可为空)中有一个带有索引设置的预订表。
在我的 Rails 应用程序中,有两个部分通过 rescheduled_reservation_id 字段查询预订,如下所示:
Transit::Reservation.find_by(rescheduled_reservation_id: 25805)
并产生以下日志输出:
Transit::Reservation Load (60.3ms) SELECT `transit_reservations`.* FROM `transit_reservations` WHERE `transit_reservations`.`deleted_at` IS NULL AND `transit_reservations`.`rescheduled_reservation_id` = 25805 LIMIT 1
但是应用程序的另一部分:
Transit::Reservation.where(rescheduled_reservation_id: 25805).last
日志输出如下
Transit::Reservation Load (2.3ms) SELECT `transit_reservations`.* FROM `transit_reservations` WHERE `transit_reservations`.`deleted_at` IS NULL AND `transit_reservations`.`rescheduled_reservation_id` = 25805 ORDER BY `transit_reservations`.`id` DESC LIMIT 1
清楚地看到第一个查询
Transit::Reservation Load (60.3ms) SELECT `transit_reservations`.* FROM `transit_reservations` WHERE `transit_reservations`.`deleted_at` IS NULL AND `transit_reservations`.`rescheduled_reservation_id` = 25805 LIMIT 1
占用了 60 毫秒,与本文档中的 2 毫秒相比,索引可能没有被正确使用
Transit::Reservation Load (2.3ms) SELECT `transit_reservations`.* FROM `transit_reservations` WHERE `transit_reservations`.`deleted_at` IS NULL AND `transit_reservations`.`rescheduled_reservation_id` = 25805 ORDER BY `transit_reservations`.`id` DESC LIMIT 1
我还尝试通过对两个查询运行解释来进一步调试,我得到了相同的结果,即正在使用的索引 rescheduled_reservation_id
有没有人遇到过这个问题?我想知道 rails mysql 连接(我正在使用 mysql2 gem)是否可能导致 MySQL 服务器没有选择正确的索引
解决方案
这很罕见,但很正常。
可能的答案是第一次出现没有找到它需要缓存在 buffer_pool 中的块。因此,它必须从磁盘中获取它们。在普通的 ole HDD 上,经验法则是每次磁盘命中 10 毫秒。因此,可能需要 6 个块来获取,导致 60.3 毫秒。
另一种可能性是其他活动正在干扰,从而减慢了此操作。
2.3ms 对于像这样的简单查询是合理的,可以完全使用 RAM 中的缓存块执行。
服务器最近是否重新启动?重新启动后,缓存中没有任何内容。桌子比 大innodb_buffer_pool_size
吗?如果是这样,那将导致 60ms 偶尔发生——块会被撞出。(警告:buffer_pool 不应该变得太大以至于发生“交换”。)
一个块是16KB;它包含 BTree 的一些数据行或索引行或节点。根据表的大小,即使是“点查询”也可能需要查看 6 个或更多块。
如果你大部分时间都没有得到 2.3ms ,我们应该更深入地挖掘。(我已经暗示要调查的尺寸。)
推荐阅读
- angular - ngModel 更改多项选择
- python - 查询集中的python django纬度经度过滤器
- sharepoint - 拒绝 SharePoint 访问但允许电子邮件
- python - 更改图表标签轴的颜色
- python - ISO3166没有正确导入方法-Pycharm
- python - Python:如何在带有“{”字符的 SQL 字符串中插入变量?
- google-cloud-firestore - Firestore子集合查询
- azure - 将 Azure 策略定义部署到管理组权限
- android - 在约束布局上,BottomNavigationView 高度计算为零
- flutter - 是否可以像在 JS 中那样在 dart(Flutter) 中实现 Future<>s 模式?