MYSQL prefer_order_index 的罪责

c2426cf8cf4a93edbe1d7594593fef82.png

开头还是介绍一下群,如果感兴趣polardb ,mongodb ,mysql ,postgresql ,redis 等有问题,有需求都可以加群群内有各大数据库行业大咖,CTO,可以解决你的问题。加群请联系 liuaustin3 ,在新加的朋友会分到2群(共700多人左右 1 + 2)。

最近我们在使用MYSQL 8 的情况下(8.025) 在数据库运行中出现一个问题 参数prefer_order_index 的问题, 熟悉 MYSQL的同学看到这个参数估计都是恨的牙根痒痒,这个参数的想法是好的,仅仅是限于想法是好的。

数据库中的优化器的工作就是选择更好的执行的方式来将SQL语句给出最好的方案来执行,那么评估一个SQL的好坏的方式就是代价cost 最小或者尽可能的小, cost 小了,则我们可以认为是  IOPS, CPU 的消耗都会减少,这就是我们希望看到的。

那么怎么能这样,回答可能是扫描的行数要少,那么用这个思路我们串一下。

MYSQL的优化器判断语句执行路径---- 评判执行计划的COST---- 扫描的行数少----成本低---  推出执行计划

2050becd8ac376f8dd8605c51796c118.png

所以这期就的说说在这样的优化思路下的 prefer_order_index 的参数在MYSQL 8 默认开启后的问题。 

4d832a7d4b3c84cca08e5f807a07941b.png

这个参数如果大家细心的情况下,在我们的MYSQL 5.7 也有这个参数,而且这个参数是关闭的见上图。先说说这个参数的历史,这个参数是在 MYSQL5.7.33 版本上产生的,目的就是为了要提高整体的SQL 在运行ORDER BY  LIMIT  GROUP BY 时,可以选择有序索引提高数据排序的的速度和 提高语句执行的效率。但是基于一贯的风格,这个参数虽然在MYSQL 5.7.33 中推出但默认是关闭的所以当时的使用这个版本的应用并未受到影响,而这个参数发布的版本也是MYSQL5.7 最靠后的版本,所以这边版本本身就使用的人少。

而后到了MYSQL8.X 这个参数得到了进化,除了对ORDER BY 和 GROUP BY 进行优化的后,还加入了 limit  的考虑的元素, 并且这个一开始的设定就是参数开启的状态,这个参数实际上在 8.021 的这个版本上重新启用了,并且一开始默认是开启的,这样一搞,就出现很多的SQL 运行时的故障。

我们看下面这个例子

a16da0531a4ba4d820d36117ad17d869.png

一个1000万的表,然后我们有相关的主键和索引,我们对这个表发起下面的查询方式。

3706d40e1d27b4c0d89526d2568da1c9.png

在打开这个参数后,用下面的语句来进行运算,则

mysql> set optimizer_switch = "prefer_ordering_index=on";

Query OK, 0 rows affected (0.00 sec)

mysql> select * from t_user where age >= 20 and age < 50 order by id limit 10;

5144daad3c5b03538c885dd764dc7993.png

mysql> set optimizer_switch = "prefer_ordering_index=off";

Query OK, 0 rows affected (0.00 sec)

mysql> select * from t_user where age >= 20 and age < 50 order by id limit 10;

28e6b91873b89b9aab7f31b8774f30bd.png

这里明显的结果是打开这个参数后,运行的结果会很快给出,但是关闭后,性能会较低。

所以在这样的情况下,可以证明打开对于数据查询的性能是有提高的,但是如果我们针对一些特殊的场景来看,这个参数打开后,会导致同一个SQL 部分SQL 稍许变动后,导致的执行计划不稳定的情况。

a25429ff968ed7363e661be3415e9441.png

mysql> set optimizer_switch = "prefer_ordering_index=on";

Query OK, 0 rows affected (0.00 sec)

mysql> 

mysql> 

mysql> explain select * from t_user where age > 20 and age < 22 order by id  limit 10,20;

+----+-------------+--------+------------+-------+---------------+---------+---------+------+------+----------+-------------+

| id | select_type | table  | partitions | type  | possible_keys | key     | key_len | ref  | rows | filtered | Extra       |

+----+-------------+--------+------------+-------+---------------+---------+---------+------+------+----------+-------------+

|  1 | SIMPLE      | t_user | NULL       | index | idx_age       | PRIMARY | 8       | NULL |  604 |     4.96 | Using where |

+----+-------------+--------+------------+-------+---------------+---------+---------+------+------+----------+-------------+

1 row in set, 1 warning (0.00 sec)

mysql> explain select * from t_user where age > 20 and age < 22 order by id  limit 10000,10010;

+----+-------------+--------+------------+-------+---------------+---------+---------+------+-------+----------+---------------------------------------+

| id | select_type | table  | partitions | type  | possible_keys | key     | key_len | ref  | rows  | filtered | Extra                                 |

+----+-------------+--------+------------+-------+---------------+---------+---------+------+-------+----------+---------------------------------------+

|  1 | SIMPLE      | t_user | NULL       | range | idx_age       | idx_age | 2       | NULL | 49484 |   100.00 | Using index condition; Using filesort |

+----+-------------+--------+------------+-------+---------------+---------+---------+------+-------+----------+---------------------------------------+

1 row in set, 1 warning (0.00 sec)

而在MYSQL 曾经提交的BUG 中也有这个部分的身影,所以 prefer_order_index 的参数是一个双刃剑,如果你打开了这个参数,那么如果你发现一些语句突发性的变慢,不要慌张,先看看是不是这个参数打开导致的问题,尤其是 order by  limit 的SQL。

如果你想更清楚问题可以查找下面的两个BUG  OF MYSQL 

  • Bug#74602: Optimizer prefers wrong index because of low limit

  • Bug#78612: Optimizer chooses wrong index for ORDER BY

912f28ffca504096ddf142b6e0638b8d.png

`cpu_prefer_performance` 是 Android 系统中与 **CPU 调度策略** 相关的一个参数,用于 **控制 CPU 核心的选择偏好**,特别是在 **大小核架构(如 ARM big.LITTLE)** 中,决定系统在任务调度时是否优先选择性能更强的大核。 --- ### ✅ 一、`cpu_prefer_performance` 的含义 - **作用**:控制 CPU 调度器是否优先选择 **性能核心(大核)** 来执行任务。 - **单位**:布尔值(0 或 1) - `0`:优先节能,调度器优先使用小核。 - `1`:优先性能,调度器优先使用大核。 - **路径示例**: - `/sys/module/sched_task_sync/parameters/cpu_prefer_performance` - `/sys/kernel/sched/cpu_prefer_performance` > 具体路径可能因设备和内核版本而异。 --- ### ✅ 二、如何通过 ADB 查看和修改 `cpu_prefer_performance` #### 1. 查看当前值 ```bash adb shell su cat /sys/module/sched_task_sync/parameters/cpu_prefer_performance ``` 输出示例: ``` 0 ``` 表示当前调度策略优先节能。 #### 2. 修改值(例如设为 1) ```bash echo 1 > /sys/module/sched_task_sync/parameters/cpu_prefer_performance ``` > ⚠️ 注意: > - 需要 root 权限。 > - 不是所有设备都支持该参数。 > - 修改为临时生效,重启后恢复默认。 --- ### ✅ 三、`cpu_prefer_performance` 的调度影响 | 设置值 | 调度策略 | 适用场景 | |--------|-----------|-----------| | `0` | 优先使用小核(节能) | 日常使用、省电模式 | | `1` | 优先使用大核(性能) | 游戏、视频编辑、性能模式 | 当设置为 `1` 时,系统会倾向于将任务分配给性能更强的大核,从而提升响应速度和处理能力,但也可能导致功耗和发热增加。 --- ### ✅ 四、与相关调度参数的区别 | 参数 | 作用 | 控制粒度 | |------|------|----------| | `cpu_prefer_performance` | 控制整体调度是否偏向性能核心 | 系统级 | | `sched_prefer_spill` | 是否允许任务溢出到其他核心 | 核心调度策略 | | `cpu_boost` | 在用户交互时临时提升 CPU 性能 | 事件触发式 | | `input_boost` | 在输入事件(如点击、滑动)时提升性能 | 用户交互优化 | --- ### 📌 注意事项 - **需要 root 权限**:大多数设备需 root 才能修改。 - **路径可能不存在**:某些设备或内核未启用该功能。 - **重启后恢复默认值**:临时修改,需脚本或模块持久化。 - **不当设置可能导致调度失衡或过热**。 --- ### ✅ 替代方案 - 使用 **Magisk 模块** 或 **内核管理器 App**(如 Franco Kernel Manager、Kernel Auditor)进行调度策略定制。 - 使用 **Termux + 自动化脚本** 实现开机自动设置。 - 使用 **系统开发者选项** 中的调度器配置(部分定制 ROM 提供)。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值