当前位置:首页 > > 架构师社区
[导读]来自:Java面试那些事儿 最近,在脉脉上看到一个楼主提出的问题:MySQL数据量大时,delete操作无法命中索引;并且还附上了相关案例截图。 最终,楼主通过开启MySQL分析优化器追踪,定位到是优化器搞的鬼,它觉得花费时间太长。因为我这个是测试数据,究其原因


我艹,MySQL数据量大时,delete操作无法命中索引。

来自:Java面试那些事儿


最近,在脉脉上看到一个楼主提出的问题:MySQL数据量大时,delete操作无法命中索引;并且还附上了相关案例截图。

我艹,MySQL数据量大时,delete操作无法命中索引。

我艹,MySQL数据量大时,delete操作无法命中索引。

我艹,MySQL数据量大时,delete操作无法命中索引。

我艹,MySQL数据量大时,delete操作无法命中索引。

最终,楼主通过开启MySQL分析优化器追踪,定位到是优化器搞的鬼,它觉得花费时间太长。因为我这个是测试数据,究其原因是因为数据倾斜,导致计算出的数据占比较大、花费时间长


大家要记住一点,一条SQL语句走哪条索引是通过其中的优化器代价分析两个部分来决定的。所以,随着数据的不断变化,最优解也要跟着变化。因此,就需要DBA来不断的优化SQL。


对于查询情况,其实MySQL提供给我们一个功能来引导优化器更好的优化,那便是MySQL的查询优化提示(Query Optimizer Hints)。比如,想让SQL强制走索引的话,可以使用 FORCE INDEX 或者USE INDEX;它们基本相同,不同点:在于就算索引的实际用处不大,FORCE INDEX也得要使用索引。

EXPLAIN SELECT * FROM yp_user FORCE INDEX(idx_gender) where gender=1 ;

同样,你也可以通过IGNORE INDEX来忽略索引。

EXPLAIN SELECT * FROM yp_user IGNORE INDEX(idx_gender) where gender=1 ;

在我看来,虽然有MySQL Hints这种好用的工具,但我建议还是不要再生产环境使用,因为当数据量增长时,你压根儿都不知道这种索引的方式是否还适应于当前的环境,还是得配合DBA从索引的结构上去优化。


接下来,我来教大家如何用MySQL的trace分析优化器是如何选择执行计划的?很重要的手段,建议多实战一下。


1、什么是Trace?


关于这个问题,我觉得去最好的描述是官方文档。

我艹,MySQL数据量大时,delete操作无法命中索引。

在MySQL 5.6中,MySQL优化器增加了一个新的跟踪功能。该接口由一组optimizer_trace_xxx系统变量和INFORMATION_SCHEMA.OPTIMIZER_TRACE表提供,但可能会发生变化。

通俗点,就是通过trace文件能够进一步了解为什么优化器选择A执行计划而不选择B执行计划,帮助我们更好的理解优化器的行为。


2、如何使用?


还是得看官方文档。

# 查看优化器跟踪是否状态SHOW VARIABLES LIKE '%optimizer_trace%';# 开启tracing (默认是关闭的):SET optimizer_trace="enabled=on";# 你的查询语句SELECT ...; # 查询trace json文件SELECT * FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE;# 当完成后,关闭traceSET optimizer_trace="enabled=off";


3、分析trace文件


根据我本地的一个例子为例,具体文件内容如下。

SELECT * FROM yp_user where gender=1 | { "steps": [ { "join_preparation": { "select#": 1, "steps": [ { "expanded_query": "/* select#1 */ select `yp_user`.`open_id` AS `open_id`,`yp_user`.`avatar_url` AS `avatar_url`,`yp_user`.`city` AS `city`,`yp_user`.`country` AS `country`,`yp_user`.`create_time` AS `create_time`,`yp_user`.`gender` AS `gender`,`yp_user`.`language` AS `language`,`yp_user`.`nick_name` AS `nick_name`,`yp_user`.`province` AS `province`,`yp_user`.`skey` AS `skey`,`yp_user`.`update_time` AS `update_time`,`yp_user`.`privilege` AS `privilege` from `yp_user` where (`yp_user`.`gender` = 1)" } ] } }, { "join_optimization": { "select#": 1, "steps": [ { "condition_processing": { "condition": "WHERE", "original_condition": "(`yp_user`.`gender` = 1)", "steps": [ { "transformation": "equality_propagation", "resulting_condition": "multiple equal(1, `yp_user`.`gender`)" }, { "transformation": "constant_propagation", "resulting_condition": "multiple equal(1, `yp_user`.`gender`)" }, { "transformation": "trivial_condition_removal", "resulting_condition": "multiple equal(1, `yp_user`.`gender`)" } ] } }, { "substitute_generated_columns": { } }, { "table_dependencies": [ { "table": "`yp_user`", "row_may_be_null": false, "map_bit": 0, "depends_on_map_bits": [ ] } ] }, { "ref_optimizer_key_uses": [ { "table": "`yp_user`", "field": "gender", "equals": "1", "null_rejecting": false } ] }, { "rows_estimation": [ { "table": "`yp_user`", "range_analysis": { "table_scan": { "rows": 3100, "cost": 719.1 }, "potential_range_indexes": [ { "index": "PRIMARY", "usable": false, "cause": "not_applicable" }, { "index": "idx_skey", "usable": false, "cause": "not_applicable" }, { "index": "idx_gender", "usable": true, "key_parts": [ "gender", "open_id" ] } ], "setup_range_conditions": [ ], "group_index_range": { "chosen": false, "cause": "not_group_by_or_distinct" }, "analyzing_range_alternatives": { "range_scan_alternatives": [ { "index": "idx_gender", "ranges": [ "1 <= gender <= 1" ], "index_dives_for_eq_ranges": true, "rowid_ordered": true, "using_mrr": false, "index_only": false, "rows": 2731, "cost": 3278.2, "chosen": false, "cause": "cost" } ], "analyzing_roworder_intersect": { "usable": false, "cause": "too_few_roworder_scans" } } } } ] }, { "considered_execution_plans": [ { "plan_prefix": [ ], "table": "`yp_user`", "best_access_path": { "considered_access_paths": [ { "access_type": "ref", "index": "idx_gender", "rows": 2731, "cost": 837.2, "chosen": true }, { "rows_to_scan": 3100, "access_type": "scan", "resulting_rows": 3100, "cost": 717, "chosen": true } ] }, "condition_filtering_pct": 100, "rows_for_plan": 3100, "cost_for_plan": 717, "chosen": true } ] }, { "attaching_conditions_to_tables": { "original_condition": "(`yp_user`.`gender` = 1)", "attached_conditions_computation": [ ], "attached_conditions_summary": [ { "table": "`yp_user`", "attached": "(`yp_user`.`gender` = 1)" } ] } }, { "refine_plan": [ { "table": "`yp_user`" } ] } ] } }, { "join_execution": { "select#": 1, "steps": [ ] } } ]}

通过这个例子,我们可以得到全表扫描的代价如下。

"table_scan": { "rows": 3100, "cost": 719.1}

分析结果:全表扫描访问的rows记录为3100,代价cost计算为719.1。


索引扫描的代价如下。

"range_scan_alternatives": [ { "index": "idx_gender", "ranges": [ "1 <= gender <= 1" ], "index_dives_for_eq_ranges": true, "rowid_ordered": true, "using_mrr": false, "index_only": false, "rows": 2731, "cost": 3278.2, "chosen": false, "cause": "cost" }]

分析结果:这里看到了通过idx_gender索引过滤时,优化器预估需要返回2731记录,访问代价cost为3278.2,大于全表扫描代价719.1;因此,优化器倾向于选择全表扫描。


今晚上就熬夜写到这里吧。


-----------------------------

特别推荐一个分享架构+算法的优质内容,还没关注的小伙伴,可以长按关注一下:

我艹,MySQL数据量大时,delete操作无法命中索引。

长按订阅更多精彩▼

我艹,MySQL数据量大时,delete操作无法命中索引。

如有收获,点个在看,诚挚感谢

免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭