首先写几个费解的例子(mysql是否走索引 都是由很多因素导致 下面写了trace工具可以进行分析)

首先这是一个聚合索引的顺序 name,age,postitonEXPLAIN SELECT * FROM emp WHERE name > 'am' AND age = 22 postition = '12'
上面这个sql第一个字段使用的是范围查找这样就不会走索引了 原因就是数据庞大 还要回表 效率很低 不如直接全表扫描 利用索引覆盖机制把它优化为 EXPLAIN SELECT name,age,postiton FROM emp WHERE name > 'am' AND age = 22 postition = '12'  也可以强制让它走索引EXPLAIN SELECT * FROM employees force index(idx_name_age_position) WHERE name > 'LiLei' AND age = 22 AND position ='manager';  加一个force index(索引名字)强制走所以可能效率也不会高 还是要根据现实进行分析 比较的时候先要把缓存关了set global query_cache_size=0;set global query_cache_type=0; 针对5.6版本及以前 这里不清楚请看前一个帖子 看了前一个帖子还不明白请来问我in和or  会在数据量庞大的时候走索引  数据很少的情况下会全表扫描
EXPLAIN SELECT * FROM employees WHERE name in ('LiLei','HanMeimei','Lucy') AND age = 22 AND position ='manager'; 可以创建两个表一个数据量庞大一个数据量很少 参考上面这个SQL的写法进行查看like KK%一般都会走索引 因为MySql有一个索引下推(Index Condition Pushdown,ICP)的机制 EXPLAIN SELECT * FROM employees WHERE name like 'LiLei%' AND age = 22 AND position ='manager';上面这个sql 在根据name查询的时候会顺便查询age、position这俩字段 这个过程就叫做索引下推机制这是在MySql5.6之后 5.6之前这种查询只会根据联合索引中匹配到KK开头的索引 然后回表去找这个主键然后再把剩下的数据找出来   范围查找(就是大于小于这种的)没有这个机制 可能是因为MySql开发人员觉得这个这种条件查询出来的数据很大要是每个都比较后面两个效率就低了

Mysql 如何选择合适的索引

首先先看一个现象EXPLAIN select * from employees where name > ‘a’;这个sql是不会走索引的随便创建一个表插入写一个存储过程插入一些数据索引就参考上面写的那三个字段进行设置就能看到现象EXPLAIN select name,age,position from employees where name > ‘a’ ;这个sql利用的索引覆盖走了索引 第一个为什么不走索引 因为写的是* 当写了*mysql就会认为在一个索引树中找不全所有的字段需要回表 但是where是一个范围查询 mysql就会认为范围查询 查出来的数据很庞大 认为回表次数多效率不如全表(不走索引)查询 第二个是因为用了索引覆盖机制

trace工具 这是一个可以查看一条sql到底怎么走的都经过了那几步

首先开启trace set session optimizer_trace=“enabled=on”,end_markers_in_json=on; --开启trace
然后随便执行一个SQL语句 select * from employees where name > ‘a’ order by position; 紧随其后SELECT * FROM information_schema.OPTIMIZER_TRACE; 这两条SELECT语句要一起执行 选中执行 然后不出意外的话就会在结果2中看到上面那条sql语句 跟 后面一个json格式的字符串 这个json字符串写的就是上面那条sql语句执行的时候都做了什么 选择了什么

查看trace字段: 这是我的结果 值可能不一样 但是意思是一样的
{"steps": [{"join_preparation": {    --第一阶段:SQL准备阶段,格式化sql"select#": 1,"steps": [{"expanded_query": "/* select#1 */ select `employees`.`id` AS `id`,`employees`.`name` AS `name`,`employees`.`age` AS `age`,`employees`.`position` AS `position`,`employees`.`hire_time` AS `hire_time` from `employees` where (`employees`.`name` > 'a') order by `employees`.`position`"}] /* steps */} /* join_preparation */},{"join_optimization": {    --第二阶段:SQL优化阶段"select#": 1,"steps": [{"condition_processing": {    --条件处理"condition": "WHERE","original_condition": "(`employees`.`name` > 'a')","steps": [{"transformation": "equality_propagation","resulting_condition": "(`employees`.`name` > 'a')"},{"transformation": "constant_propagation","resulting_condition": "(`employees`.`name` > 'a')"},{"transformation": "trivial_condition_removal","resulting_condition": "(`employees`.`name` > 'a')"}] /* steps */} /* condition_processing */},{"substitute_generated_columns": {} /* substitute_generated_columns */},{"table_dependencies": [    --表依赖详情{"table": "`employees`","row_may_be_null": false,"map_bit": 0,"depends_on_map_bits": [] /* depends_on_map_bits */}] /* table_dependencies */},{"ref_optimizer_key_uses": [] /* ref_optimizer_key_uses */},{"rows_estimation": [    --预估表的访问成本{"table": "`employees`","range_analysis": {"table_scan": {     --全表扫描情况"rows": 10123,    --扫描行数"cost": 2054.7    --查询成本  下面还有这个cost mysql会根据这个判断是否使用索引} /* table_scan */,"potential_range_indexes": [    --查询可能使用的索引{"index": "PRIMARY",    --主键索引"usable": false,"cause": "not_applicable"},{"index": "idx_name_age_position",    --辅助索引"usable": true,"key_parts": ["name","age","position","id"] /* key_parts */}] /* potential_range_indexes */,"setup_range_conditions": [] /* setup_range_conditions */,"group_index_range": {"chosen": false,"cause": "not_group_by_or_distinct"} /* group_index_range */,"analyzing_range_alternatives": {    --分析各个索引使用成本"range_scan_alternatives": [{"index": "idx_name_age_position","ranges": ["a < name"      --索引使用范围] /* ranges */,"index_dives_for_eq_ranges": true,"rowid_ordered": false,    --使用该索引获取的记录是否按照主键排序"using_mrr": false,"index_only": false,       --是否使用覆盖索引"rows": 5061,              --索引扫描行数"cost": 6074.2,            --索引使用成本"chosen": false,           --是否选择该索引"cause": "cost"}] /* range_scan_alternatives */,"analyzing_roworder_intersect": {"usable": false,"cause": "too_few_roworder_scans"} /* analyzing_roworder_intersect */} /* analyzing_range_alternatives */} /* range_analysis */}] /* rows_estimation */},{"considered_execution_plans": [{"plan_prefix": [] /* plan_prefix */,"table": "`employees`","best_access_path": {    --最优访问路径"considered_access_paths": [   --最终选择的访问路径{"rows_to_scan": 10123,"access_type": "scan",     --访问类型:为scan,全表扫描"resulting_rows": 10123,"cost": 2052.6,"chosen": true,            --确定选择"use_tmp_table": true}] /* considered_access_paths */} /* best_access_path */,"condition_filtering_pct": 100,"rows_for_plan": 10123,"cost_for_plan": 2052.6,"sort_cost": 10123,"new_cost_for_plan": 12176,"chosen": true}] /* considered_execution_plans */},{"attaching_conditions_to_tables": {"original_condition": "(`employees`.`name` > 'a')","attached_conditions_computation": [] /* attached_conditions_computation */,"attached_conditions_summary": [{"table": "`employees`","attached": "(`employees`.`name` > 'a')"}] /* attached_conditions_summary */} /* attaching_conditions_to_tables */},{"clause_processing": {"clause": "ORDER BY","original_clause": "`employees`.`position`","items": [{"item": "`employees`.`position`"}] /* items */,"resulting_clause_is_simple": true,"resulting_clause": "`employees`.`position`"} /* clause_processing */},{"reconsidering_access_paths_for_index_ordering": {"clause": "ORDER BY","steps": [] /* steps */,"index_order_summary": {"table": "`employees`","index_provides_order": false,"order_direction": "undefined","index": "unknown","plan_changed": false} /* index_order_summary */} /* reconsidering_access_paths_for_index_ordering */},{"refine_plan": [{"table": "`employees`"}] /* refine_plan */}] /* steps */} /* join_optimization */},{"join_execution": {    --第三阶段:SQL执行阶段"select#": 1,"steps": [] /* steps */} /* join_execution */}] /* steps */
}

结论:全表扫描的成本低于索引扫描
set session optimizer_trace=“enabled=off”; --关闭trace

Order by与Group by

它们两个也可以遵循最左前缀原则使用索引 比如 EXPLAIN
select * from emp where name = 'll' and position = 'aaa' orderby age;  这时 name会用索引 age会用索引 position不会用索引  Order by跟Group by是否用索引 看Extra列 如果是Using index就是使用了索引 不是index就是 filesort 在where把position删了然后在age后面写position这样都会用索引它俩位置颠倒了就不可以了  还有EXPLAIN select * from emp where name = 'll' and age = 'aaa' order by position,age;   这样也会用索引 age会被优化 会把order by后面的age给优化没 要是对order by后面一个升序一个降序那么它也不会走索引 因为违背了索引的排序 使用in or也不会走索引 因为在排序中会认为in或or是范围查询查出来的数据

Using filesort文件排序原理

有两种方式 单路排序 双路排序

用trace工具可以看到sort_mode这个单词 后面跟着的是< sort_key, additional_fields >这个它就是单路排序如果是< sort_key, rowid >这个就是双路排序单路排序是把全部数据放到一个mysql给我们初始化的一块空
间中叫做sort_buffer 在这里面完成排序 这个缓存也是有大小
的 要是超过了这个大小 它会在磁盘上创建临时文件把这些数
据放进去 然后在读取到内存 这时就不是在sort_buffer中了 然
后排好序在返回双路排序就是把id跟要排序的字段放入内存进行排序 排好序在根据id去把相应的数据查询出来 然后返回 这个效率有点低MySQL是通过比较系统变量max_length_for_sort_data(默认1024字节)这些数据大于这个值就是用双路排序 如果小于这个值 就用单路排序

索引设计思想
一个表不要创建单个字段的索引 创建聚合索引满足索引覆盖效率才好

先写代码程序 然后根据业务常用字段设置索引优化SQL
联合索引尽量使用索引覆盖机制 在基数大的字段上加索引
where跟order 优先让where使用索引例子比如一个app探探、百合网、陌陌这种交友软件 肯定
会有地址、性别、爱好、身高、年龄、评分、近期是否登
录等这几个字段 肯定会有 select xxx from xxx where 地
址=xx,性别=xx,爱好=xx.身高=xx.年龄>=xxand年龄<=xx
评分(曝光度)=xx,近期是否登录 这种sql语句 就可以进
行分析加索引 地址我们在用这种软件的正常情况下会选择
同城的吧一般不会我在济南 然后我选择一个甘肃的异地恋所以第一个索引地址 然后在分析性别我们也得选择吧男的一般都会过滤男的女的过滤女的男看女 女看男正常情况下 有的人就是男的喜欢男的所以可以再地址后面加上性别这个字段 然后再分析年龄那咱们男的来说肯定得要十七八的小姑凉吧 年龄得还得有一个范围比如10-20岁这样我们在加上年龄 现在的索引就是地址、性别、年龄 然后在分析评分跟近期是否登录 要是一个人是个骗子给你推荐过来了不是很难受所以要有一个评分从好到坏的 近期是否登录比如一个人就是注册了玩几个小时不玩了 肯定你给它发消息不会回复你啊 回复了不就出轨(出鬼)了这种人也得给过滤掉吧 所以再加上这俩索引 然后就是 地址、性别、近期是否登录、年龄 评分不能索引因为年龄是一个范围型查询 索引会失效了 这也是为什么年龄要排在后面 再加上优化手段就是优先满足where order by可以不用管影响不会很大因为经过前面的判断加上分页返回的结果集不会很大了 以上就是一个思想吧

mysql这部分的内容都要有一些例子看运行结果才好明白光文字实在有点难 可以根据我上面写的思想写一下看一个结果就行

MySql索引优化一(算是白话)有问题欢迎评论相关推荐

  1. MySQL索引优化分析

    转载来源:https://www.cnblogs.com/itdragon/p/8146439.html MySQL索引优化分析 为什么你写的sql查询慢?为什么你建的索引常失效?通过本章内容,你将学 ...

  2. MySQL第12天:MySQL索引优化分析之性能优化案例实践

    MySQL索引优化分析之性能优化案例实践 执行计划中各select_type含义可以看:MySQL第11天:MySQL索引优化分析之性能分析 https://weibo01.blog.csdn.net ...

  3. MySQL第11天:MySQL索引优化分析之性能分析

    MySQL索引优化分析之性能分析 一.MySQL Query Optimizer 二.MySQL常见瓶颈 三.Explain(执行计划) 1.什么是执行计划?          2.执行计划能干什么? ...

  4. MySQL第10天:MySQL索引优化分析之索引介绍

    MySQL索引优化分析之索引简介 1.索引是什么? 2.索引优势.劣势 3.索引分类.基本语法 4.索引结构 5.哪些情况需要创建索引? 6.哪些情况不需要创建索引? ---------------- ...

  5. MySQL第9天:MySQL索引优化分析之join查询

    MySQL索引优化分析之join查询 #编写时间:2017.3.12 #编写地点:广州 常见join查询: 1.SQL执行顺序:手写.机读.总结 (1)手写 (2)机读 (3)总结 2.join图 3 ...

  6. MySQL第8天:MySQL索引优化分析之SQL慢

    MySQL索引优化分析之SQL慢 #编写时间:2017.3.11 #编写地点:广州 性能下降SQL慢,执行时间长,等待时间长的原因有: (1)查询语句写的不合理 (2)索引失效:单值索引.符合索引 ( ...

  7. 讲真,MySQL索引优化看这篇文章就够了

    本文主要讨论MySQL索引的部分知识.将会从MySQL索引基础.索引优化实战和数据库索引背后的数据结构三部分相关内容,下面一一展开. 一.MySQL--索引基础 首先,我们将从索引基础开始介绍一下什么 ...

  8. mysql物理删除索引_mysql创建索引,mysql索引优化,mysql索引创建删除

    mysql创建索引,mysql索引优化,mysql索引创建删除 ================================ ©Copyright 蕃薯耀 2020-11-23 http://fa ...

  9. MySQL索引优化是什么意思?底层原理是什么?

    MySQL索引优化是指通过对MySQL数据库中的索引进行优化,提高查询性能和效率的过程.索引是一种数据库对象,它可以提高查询数据的速度,通过创建索引可以使得查询操作更快速.更高效. 底层原理是:MyS ...

  10. mysql索引优化有几种_mysql索引优化

    索引类型 从物理存储角度上,索引可以分为聚集索引和非聚集索引. 1.聚集索引(Clustered Index) 聚集索引决定数据在磁盘上的物理排序,一个表只能有一个聚集索引. 2.非聚集索引(Non- ...

最新文章

  1. 通俗易懂的ReentrantLock,不懂你来砍我
  2. redis探秘:选择合适的数据结构,减少80%的内存占用,这些点你get到了吗?
  3. python笔记记录(包和模块)
  4. 常见设计模式描术(看完就把它忘记~~)
  5. 洛谷 [P2964] 硬币的游戏
  6. 编写Linux Shell脚本的最佳实践
  7. 微信小程序上传图片到云储存
  8. 怎么用C语言读取gcode文件,arduino当Gcode解释程序(CNC)
  9. 误删通话记录?这几个方法能恢复
  10. 【开发随机】JAVA+POI+自定义注解+反射构建自定义工具类实现快捷简便的Excel模板化导出(附demo代码)
  11. mysql所选路径已经存在_「mysql第二次安装不了」mysql安装失败怎么清理干净?
  12. 我国各城市间航空班次
  13. Java图书管理_增删改查_分层实现功能
  14. Python破解携程点击文字验证
  15. 「免费资源」微信小程序入门与实战
  16. querylist.php下载,PHP 强大的采集工具,QueryList
  17. Qt for Android 程序实现对手机文件的导入打开与导出保存
  18. 阿里云开源业界首个面向NLP场景深度迁移学习框架
  19. 计算10的阶乘以及10以内阶乘的和
  20. 2021年焊工(技师)考试及焊工(技师)模拟考试

热门文章

  1. 电商类应用如何快速构建站内搜索和智能推荐能力?
  2. 2022-02-17T16:00:00.000Z时间格式的转换
  3. rabbitmq知识汇总
  4. 【参赛作品55】openGauss出现双主
  5. 报错:使用java api连接redis集群时报错 READONLY You can't write against a read only slave.
  6. 如何检查iPhone或iPad是否存在无法在iOS 11上运行的32位应用程序
  7. 带你解锁AC/DC、DC/DC转换器基础
  8. 京喜无货源怎么样?京东2020严打无货源后,能带给京喜什么利益?
  9. Nginx 概述 如何正规安装 静态网页配置 反向代理配置 负载均衡配置
  10. Element 横向表格