请问MySQL索引是如何选择的?on、where、order by中的字段谁的优先级更高?
该SQL为啥没有用idx_issue_id索引?
请问MySQL索引是如何选择的?on、where、order by中的字段谁的优先级更高?
该SQL为啥没有用idx_issue_id索引?
在MySQL中,索引的选择并不是简单地基于 ON
、WHERE
或 ORDER BY
子句中的字段优先级来决定的。MySQL 的查询优化器会根据多种因素综合考虑来选择最优的索引,这些因素包括但不限于:
WHERE
子句中的条件对于索引选择至关重要,因为索引主要用于加速条件过滤。JOIN
操作中,ON
子句的条件也会影响索引的选择。ORDER BY
能够利用索引进行排序,优化器可能会选择该索引。具体到你的问题,为什么给定的查询没有使用 idx_issue_id
索引,可能有以下原因:
idx_issue_id
可能不是针对当前查询条件的最优索引。例如,如果查询中使用了其他条件,并且这些条件在 idx_issue_id
索引中不是前缀列,那么该索引可能不会被使用。idx_issue_id
看起来是一个合理的选择,优化器也可能出于性能考虑(如减少IO操作、避免随机访问等)而选择其他索引或全表扫描。要确定为什么 idx_issue_id
没有被使用,你可以使用 EXPLAIN
语句来查看查询的执行计划,并分析其中的索引使用情况。根据 EXPLAIN
的输出,你可以调整索引设计、查询条件或表结构,以优化查询性能。
EXPLAIN SELECT * FROM your_table WHERE your_conditions ORDER BY your_order_columns;
通过 EXPLAIN
的输出,你可以看到 MySQL 优化器是如何决定使用哪个索引(或是否使用索引)来执行你的查询的。
你可以先了解一下一个 SQL 语句在 MySQL 中的执行流程,基本会执行以下阶段
连接器(Connection Manager):负责处理客户端与服务器之间的连接。它接受来自客户端的请求,并进行身份验证和权限检查,建立和管理连接。
你的问题就设计到优化器的选择,优化器的选择并不是根据语句中的on、where、order by 来进行选择使用的索引的。而是会对成本进行估算,优化器会为每个候选计划估算成本。成本基于以下因素:
根据每个执行计划的估算成本,选择成本最低的执行计划。(这就涉及一个小的 tips: 索引失效的情况其中其中有一个就是: 当某个值出现在表的数据行中的百分比很高的时候比如说type=1占百分之80的数据你使用type索引时
,优化器发现成本很高的时候,就会出现忽略掉索引使用全表查询)。
结论: Mysql 索引的选择是优化器基于查询的成本来进行选择的,并不存在优先级,建议你可以去了解可以看一下这几篇文章,会对你理解索引有更好的帮助
看标题描述,应该是有2个疑问待解答,发表下个人的看法,希望能帮到您
改进建议是:使用复合索引,甚至覆盖索引来满足要求。
在这个语句中,其实已经能看到,选择 idx_teacher_id 是因为 ref 为 const,这个成本几乎是最低的,因为要先通过这一步来缩小筛选范围。
而后面的 as_status 则是因为是 <>
查询,所以铁定不走索引的。
因为现在 teacher_id 的成本很低,所以如果你想要这里的 issues_id 也走上索引,可以考虑创建一个 teacher_id+issuse_id 的联合索引。
这样应该就能照顾到了。
MySQL索引选择机制
MySQL 优化器在选择索引时,会综合考虑多种因素来决定使用哪个索引能以最高效的方式执行查询:
WHERE
子句、JOIN
条件等查询条件的满足程度。如果某个索引能够覆盖更多的查询条件过滤数据,就更有可能被选择。on、where、order by中字段优先级
在 MySQL 中,
ON
、WHERE
、ORDER BY
子句中的字段并没有固定的绝对优先级顺序。优化器会根据具体的查询语句结构、表结构、索引情况等进行综合分析和判断。ON
子句:主要用于表连接时定义连接条件,在连接操作中起着关键作用,它决定了如何将不同表的数据进行匹配。WHERE
子句:用于筛选行,过滤出满足特定条件的记录。优化器会优先考虑能够快速过滤掉大量数据的条件,不管这些条件是在ON
还是WHERE
中。ORDER BY
子句:用于对查询结果进行排序。如果有合适的索引可以满足排序需求(索引的顺序与ORDER BY
一致),那么可以避免额外的排序操作(Filesort),否则可能会影响查询性能。该SQL未使用idx_issue_id索引的原因
在给定的 SQL 中,未使用
idx_issue_id
索引可能有以下原因:idx_issue_id
索引,但优化器评估后发现它对过滤数据的效果不如其他索引(如idx_teacher_id
)。例如,idx_teacher_id
索引对应的列teacher_id
的值为固定值57
,在过滤数据时可能更有效,而idx_issue_id
索引可能在过滤数据方面效果不佳,导致优化器选择了其他索引。idx_teacher_id
等索引可能更能够满足查询结果的获取,例如可能包含了更多查询需要的列,避免了回表操作,而idx_issue_id
索引无法满足这种覆盖需求,所以优化器没有选择它 。ANALYZE TABLE
语句来更新表的统计信息,让优化器获取更准确的数据从而做出更合理的索引选择。