QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1723|回复: 0
打印 上一主题 下一主题

mysql索引和explain的详解

[复制链接]
字体大小: 正常 放大
杨利霞        

5273

主题

82

听众

17万

积分

  • TA的每日心情
    开心
    2021-8-11 17:59
  • 签到天数: 17 天

    [LV.4]偶尔看看III

    网络挑战赛参赛者

    网络挑战赛参赛者

    自我介绍
    本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。

    群组2018美赛大象算法课程

    群组2018美赛护航培训课程

    群组2019年 数学中国站长建

    群组2019年数据分析师课程

    群组2018年大象老师国赛优

    跳转到指定楼层
    1#
    发表于 2020-5-3 15:46 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    : \  q: w7 I1 N
    mysql索引和explain的详解索引原理分析
    ; f5 Q% @9 {8 @# h6 R( m9 E* z1 ?* E+ P) V# v2 y6 K$ s
    索引存储结构( S( p+ |" K7 b0 W0 I; j4 t7 g7 I* X
    索引是在存储引擎中实现的,也就是说不同的存储引擎,会使使用不同的索引
    9 X, z) Z% h6 c7 EMyISAM和InnoDB存储引擎:只支持B+ TREE索引, 也不能够更换3 X0 W2 ~' `8 P7 B+ ^! ~& n6 H
    MEMORY/HEAP存储引擎:支持HASH和BTREE索引( [* X8 Q/ [+ a
    " _& l5 Z* s) \/ B& A* B
    B树图示5 N4 |* W! ^, v* A

    ) X$ A( [4 ^5 k# P6 V' P, PB树是为了磁盘或其它存储设备设计的一种多叉(下面你会看到,相对于二叉,B树每个内结点有多个分支,即多叉)平衡查找树。 多叉平衡。2 @5 \) q3 H7 u7 B
    ' e* A) L& Y: C' B/ V
    1.png
    : H2 j) G: ~; B( |4 n9 t- r! v4 o) L$ f/ v& W4 p& l. s
    0 [7 U9 _8 T# Y, O# [+ Y
    B树和B+树的区别:# {2 l# u1 V9 g
    B树和B+树的最大区别在于非叶子节点是否存储数据的问题% l8 v1 {1 K: ~0 a
    % h) L+ {' o7 L1 n* \+ E7 G" G
    在结构上:
    , v& u0 l! m$ H8 [* N4 t* p(1) B树是非也只节点和叶子节点都会存储数据。
    . g3 S- m: ]& P( \' _% _(2) B+树只有叶子节点才会存储数据,而且数据都是在一行上,而且这些数据都是指针指向的,也是有顺序的。; y! i7 f8 [. |  w& Z# E: o

    : B' X  I& T/ M4 e6 T2 Q在性能上:& `/ N  A& e% C$ [3 T
    (1)对于B-树相对于B+数据,B-Tree因为非叶子结点也保存具体数据,所以在查找某个关键字的时候找到即可返回。而B+Tree所有的数据都在叶子结点,每次查找都得到叶子结点。所以在同样高度的B-Tree和B+Tree中,B-Tree查找某个关键字的效率更高。B-Tree在单条数据读写有着更强的性能。( f- [1 C; _8 Y0 p
    (2)但由于B+Tree所有的数据都在叶子结点,并且结点之间有指针连接,在找大于某个关键字或者小于某个关键字的数据的时候,B+Tree只需要找到该关键字然后沿着链表遍历就可以了,而B-Tree还需要遍历该关键字结点的根结点去搜索。这个也决定当连表查询的时候mysql比起mongo有显著的优势。更重要的是由于B-Tree的每个结点(这里的结点可以理解为一个数据页)都存储主键+实际数据,而B+Tree非叶子结点只存储关键字信息,而每个页的大小有限是有限的,所以同一页能存储的B-Tree的数据会比B+Tree存储的更少。这样同样总量的数据,B-Tree的深度会更大,增大查询时的磁盘I/O次数,进而影响查询效率。: C  p+ G5 b# i$ a+ y2 s! {& Y
      H2 @6 ^1 O: m. o/ e6 n- G
    聚集索引(MyISAM)6 X8 A# y2 T1 ?
    B+树叶节点只会存储数据行(数据文件)的指针,简单来说数据和索引不在一起,就是聚集# n# v6 {4 l$ n  d2 B6 ~
    索引。6 j6 l0 j! G, f  H0 F: ^
    聚集索引包含主键索引和辅助索引都会存储数据指针的值。
    " @+ P3 @8 e; \. h1 R4 u+ H9 g
    9 q4 W& |- J) A( V8 I$ f3 F 2.png
    ' [% e# F7 G. a8 f! K7 G, \) o* c, w0 x1 y5 z4 ]
    辅助索引(次要索引)
    / Z! r; X2 J( {2 j7 a; Q/ U8 G; O在 MyISAM 中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求 key 是唯一的,1 U* u) @/ V2 x/ }0 l7 r) [7 _
    而辅助索引的 key 可以重复。如果我们在 Col2 上建立一个辅助索引,则此索引的结构如下图所示4 D+ ~4 O, u1 c9 Z# c2 ~
    3.png
    : [# i2 {% d5 ^& L& l) o同样也是一颗 B+Tree,叶子节点中保存数据记录的地址。因此,MyISAM 中索引检索的算法为首先按照B+Tree 搜索算法搜索索引,如果指定的 Key 存在,则取出其data 域的值,然后以 data 域的值为地址,读取相应数据记录。% U' I8 x0 ?5 |6 i. X

    ; r$ {9 U- W. x2 ]; b4 z聚集索引(InnoDB)3 C4 B" s, }- a/ I, `- O

    ' z% m' Q. H% z. R主键索引(聚集索引)的叶子节点会存储数据行,也就是说数据和索引是在一起,这就是聚集索引。
    2 x7 N, d& S: x辅助索引只会存储主键值
    6 C& D# z, N5 ^' W如果没有没有主键,则使用唯一索引建立聚集索引;如果没有唯一索引,MySQL会按照一定规则创建聚集索引。5 {2 j# y  s5 Z

    0 N8 O) Y. h/ p6 E  l/ G% V4 a" G主键索引
    ) l* h$ N/ F' a! w" \! Y: ]3 d1.InnoDB 要求表必须有主键(MyISAM 可以没有),如果没有显式指定,则 MySQL系统会自动选择一个可以2 @7 _& S8 _4 e% k
    唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL 自动为 InnoDB 表生成一个隐含字段作为主键,类型为长整形。# j8 g$ }5 h3 ^
    * p3 c$ Y6 ~" F  L3 N9 l( q
    4.png
    5 a- |! t1 V1 J4 a+ M2 O- L" Y' {, e& v& t' c0 m
    5 @9 h) |- |/ `% q3 q0 N- m6 v9 D
    上图是 InnoDB 主索引(同时也是数据文件)的示意图,可以看到叶节点包含了完整的数据记录。这种索引叫做聚集索引。因为 InnoDB 的数据文件本身要按主键聚集。5 \4 Q/ C! E! ]* f2 [8 t8 i1 }3 D+ h
    5.png 3 n# e% l0 Z: W( L3 M0 R' g4 n* c
    4 u% |5 W4 e; S; l4 O1 G
    $ j9 v; x9 G& s8 p
    6.png
    9 w) S8 G# k5 m. S( i: y! O) S
    3 a3 E% K, |& H% {( _. f; D: C% T
      G8 g! o% O; A/ P* `: ~mysql创建索引的时候和用法与索引息息相关,要建立合适的索引和理解一些索引的执行计划,就需要认识索引的结构。% o7 E: N8 ]  J" _& ]

    % x6 w! u1 _, F3 ~explain的详解' a. {# `, N/ e, e* m1 d4 C7 v
    ( q$ j# b* \- x1 J5 e
    参数说明:" h. w6 _1 M# z4 b- G" C3 {
    explain后会出现十列数据,下面将介绍这下面的十列数据。
    9 g3 L# a+ g- U  V" P  {  g  f- h: I! a4 f- m
    id、select_type、table、type、possible_keys、key、key_len、ref、rows、Extra
    $ \3 O* k  A& f' q2 j" U( z! t, _
    . ^9 k6 V1 z, T( @2 ~8 ?' T先附上案例表:
    4 w* f, H! Z7 g# Q
      J$ P" L! o* d! s  ~8 PCREATE TABLE `taddr` (
    4 q7 S) R! R* f1 V, w  `id` int(11) NOT NULL AUTO_INCREMENT,
    : [) C  W7 b# K1 P1 \  `country` varchar(100) DEFAULT '',
    - X0 D! h. D$ E/ c( s5 k2 I5 _  `province` varchar(100) DEFAULT '',: a+ O" ^: i( Q
      PRIMARY KEY (`id`)
    . i/ m: L% q! o* A) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8, z* J" ~. u/ N0 W

    ( _0 O' v  _: }; ]CREATE TABLE `user`  (; y; i+ f; N9 Y7 i
      `id` int(11) NOT NULL AUTO_INCREMENT,
    # k8 `2 Y0 ^) H& E  `username` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
    % c  Y" h- N) Q5 [2 ^4 T  `password` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,- n; \. N2 a! l3 L
      `name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
    0 H6 `, h! W/ a9 \$ o' F8 B  `addr_id` int(11) NULL DEFAULT NULL,
    & K5 l* V$ U6 y+ Q0 Q& U4 g1 m" c) X  PRIMARY KEY (`id`) USING BTREE,; E3 h' \! h% V& S, o5 C9 T2 K
      INDEX `addr_id`(`addr_id`) USING BTREE% u! w8 A% B! {6 z$ i) Q. L
    ) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;, t  f$ Z9 V, Y5 ]6 g

    , I! f% y8 j% O% ]" ]2 @5 O
    2 f( W% H! g' r/ ~' d+ D8 gCREATE TABLE `type_time` (  B8 a/ m! |" x+ v
      `id` int(11) NOT NULL AUTO_INCREMENT,
    " e5 T. v! l" @3 A% O5 I! D  `time` varchar(255) DEFAULT '[]',  g! p% K( D( F; z% m6 {. Y
      `name` varchar(100) DEFAULT '',
    7 i3 ]' e0 u" Y  E  PRIMARY KEY (`id`),' n# \5 t% {. F- |: l, B) c0 t
      INDEX `name_time_index`(`name`,`time`) USING BTREE
    6 z" e  e* V( w, P/ g. z0 D( E. ^) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf81 X3 v0 h" o0 i( T% c$ p
    ; `! I/ c- I6 u) A9 @
    一、id
    ( F+ G. k# k( R5 \$ L$ F7 @  R每个 SELECT语句都会自动分配的一个唯一标识符.* B! t1 F2 x% O' ], K. M+ U
    表示查询中操作表的顺序,有三种情况:
    , ~- d! Y% ]; o/ Y% sid相同:执行顺序由上到下& F! q; l& a+ E. Y6 l, Y* m& g1 w: N
    id不同:如果是子查询,id号会自增,id越大,优先级越高。
    / u7 l+ ~6 Q  o) U2 `id相同的不同的同时存在
    1 [1 Q% U1 g- s6 |1 ^- Nid列为null的就表示这是一个结果集,不需要使用它来进行查询。# q+ s8 I0 ]( W- {

    8 Z6 X. R7 x+ Y2 ~& O二、select_type1 n- J& b2 L+ \7 f$ D$ p
    + ^3 @& M5 z* ]- r/ [+ ?# v
    查询类型,主要用于区别普通查询、联合查询(union、union all)、子查询等复杂查询3 ~: h( G1 _& E) O

    ; Q+ R1 j) L0 u2 w) @2.1、simple! ~+ C; S4 ]4 d6 Q" b+ Z
    表示不需要union操作或者不包含子查询的简单select查询。有连接查询时,外层的查询为simple9 _5 Z) _8 k) e" K2 \
    5 {: z4 S+ v, i/ d
    EXPLAIN select * from user
    * S; o" `5 y7 m* n! Z3 y! o( D. g4 m. n8 n- s8 n* ?
    7.png * z# ~0 N  o: E
    5 B2 E# u, R+ G9 G$ p. x
    EXPLAIN select u.id,u.addr_id,a.* from user u inner join taddr a on u.addr_id=a.id
    8 a# v0 G$ N! j" _/ c% ~ 9.png % c  g- M4 ]% [$ M  W0 q% v3 l
    + F$ L& r9 C1 j$ f  @$ U4 y
    2.2 primary7 N0 {& r5 N* Z
    一个需要union操作或者含有子查询的select,位于最外层的单位查询的select_type为primary。2 o, y/ H+ o8 ?+ \) o: h0 s' x5 ^2 e

    + S, \1 G& a( s6 B. Z: wexplain select * from taddr t inner join (" q6 K) @+ |' i7 M
    select addr_id from user ) u on t.id=u.addr_id
    2 ?; I8 V$ ?4 l, U3 }0 C0 C 10.png 1 X/ A9 K# _5 W, ?: l9 {
    explain select * from user u where u.addr_id =1q
    . f2 H# p. A) S/ E/ P3 }union all: c( e. ^9 A* U; f
    select * from user u where u.addr_id =2
    1 w0 y, h. ^7 R+ g 11.png 0 i4 P' N: S" h. r- T

    , b! B8 d/ }8 S2.3 subquery
    $ }5 I- v9 X1 n' B. k7 Z8 Q( u( d除了from字句中包含的一查询外,其他地方出现的子查询都可能是subquery) V$ Q+ l3 N$ n* I' @
    1 J1 r% }  r! J6 H
    2.4 dependent subquery0 h+ T% i& @, L" n$ x
    1 U1 \9 ?  j, z6 u# A# H2 n
    与dependent union类似,表示这个subquery的查询要受到外部表查询的影响4 F4 }% u! U  N

    0 h+ F! n1 W8 B1 yexplain select u.name,(select t.province from taddr t where u.addr_id=t.id) from user u
    7 M  Y5 P& `: \# ~1 b 12.png 3 P2 \' p# p. {/ Q* H
    2.5 union" X- u" ]9 v- K; M) Y) P
    union连接的两个select查询,第⼀个查询是PRIMARY,除了第一个表外,第二个以后的表select_type都是union
      f# {4 M$ Y, m& _2 H
    1 _+ b; K/ Y6 t. E' H三、table" q* f% W" n7 _" D6 W
    显示的查询表名,如果查询使用了别名,那么这里显示的是别名
    4 ]1 k. P+ [; `如果不涉及对数据表的操作,那么这显示为null# k+ o) L4 A0 q5 H7 k! J4 ^
    如果显示为尖括号括起来的就表示这个是临时表,后边的N就是执行计划中的id,表示结果来自于这个查询产生。2 }) u* i8 P/ b
    如果是尖括号括起来的<union M,N>,与类似,也是一个临时表,表示这个结果来自于union查询的id为M,N的结果集。0 k) S, q$ [6 ^" w9 Y4 \( t

    - h' W! Q) R. o8 }0 I1 h3 @四、type
    6 T- P4 D* i; `
    7 I! K# r" P1 t: w$ b依次从好到差:
    , A! e+ }2 X0 }5 X3 }9 S) @$ ~system,const,eq_ref,ref,fulltext,ref_or_null,unique_subquery,& K6 t( C9 L# \
    index_subquery,range,index_merge,index,ALL& q0 m( ]3 g3 p* b" A5 N
    . S+ I3 v* B, M6 Q% a4 t
    除了all之外,其他的type都可以使⽤到索引,除了index_merge之外,其他的type只可以用到一个索引
    $ c& z0 V$ t3 K- ~5 N: V4 ?, |$ Z/ k$ Z
    4、1 system+ `4 K# e; A9 N
    表中只有一行数据或者是空表。. |# I$ b& O2 v4 O8 p( l7 }
    ( E" Z: [- F$ H2 i, E6 G1 V
    4、2const5 l) K3 u$ K4 ^1 O% n+ n; g
    使用唯一索引或者主键,返回记录一定是1行记录的等值where条件时,通常type是const。其他数据库也叫做唯一索引扫描。8 `7 j' _! h6 r3 M/ j

    # R; x0 A& ]7 ^4 ^- Q- b  n( e; j4、3 eq_ref9 G8 D9 ^: K; w- ?/ r
    关键字:连接字段主键或者唯一性索引。. C% L; c+ Z" [% x
    此类型通常出现在多表的 join 查询, 表示对于前表的每一个结果, 都只能匹配到后表的一行结果. 并且查询的比较较操作通常是 ‘=’, 查询效率较高.
    , Y1 Y* u/ L6 M# v7 |% U- ]+ n9 D: A3 n' G( _2 D8 ?& q5 K
    EXPLAIN select u.id,u.addr_id,a.* from user u inner join taddr a on u.addr_id=a.id! b, J$ F, m2 m! C

    ) z1 B& ^0 l" h' _$ Q& s! c' |: g8 O# `  R
    13.png 4 _+ Q; r8 p8 ^9 ^6 f7 m4 o

    6 K/ B$ G: c+ \$ l3 i. z9 N7 E! {8 C/ }6 f( m( C

    4、4 ref
    , f7 _9 b* V( ^, i* k) a针对非唯一性索引,使用等值(=)查询非主键。或者是使用了最左前缀规则索引的查询。

    EXPLAIN select u.id,u.addr_id,a.* from taddr a left join user u on u.addr_id=a.id

    14.png - P, r- h0 c2 t5 Z

    & k$ S$ v4 E3 r; T3 ]4.5 fulltext
    8 T; c3 ^* S; r8 R7 _( }4 O全文索引检索,要注意,全文索引的优先级很高,若全高索引和普通索引同时存在时,mysql不管代价,优先选择使用全文索引
    % {0 @6 u4 ?) k6 y6 ]4 H" a8 H  Y: T
      O% X9 w6 m; m/ W4、6 unique_subquery7 ~2 c" l8 {9 b* s
    用于where中的in形式子查询,子查询返回不重复值唯一值$ }+ y% y/ ]7 e, ~. O8 ^' d
    : x0 S$ n/ ]+ M0 k/ X0 g
    4、7 index_subquery
    ) _! R+ z0 ^5 I1 J4 W' R, n用于in形式子查询使用到了辅助索引或者in常数列表,子查询可能返回重复值,可以使用索引将子查询去重。6 X1 s; |3 Y. d
    $ {4 V! [3 Y( n9 `; w1 @
    4、8 range6 [" i2 O8 @; h! g% v% P
    索引范围扫描,常用于使用>,<,is null,between ,in ,like等运算符的查询中。
    . c0 t$ \7 ~  ]8 o
    " G9 X  ^2 ~5 l7 z& p" x$ A7 uexplain select * from type_time a inner join (
    + f7 s+ ^( R5 ]' bselect id from type_time where name =‘2’ and time in (‘2’,‘3’,‘4’) ) b on a.id=b.id% l7 X" B8 D. M( t

    " K9 v! Y; K) U$ H$ E9 l) Y
    # {& L; h, Q) u5 L 15.png
    : ^; ^( P! h  M  F+ G7 D/ }8 H1 A) ?7 ~
    4、9 index
    * O% X, q: |3 @8 r6 s7 U键字:条件是出现在索引树中的节点的。可能没有完全匹配索引。" j/ f$ w& F$ y% g0 z4 K7 _
    索引全表扫描,把索引从头到尾扫一遍,常用于使用索引列就可以处理不需要读取数据文件的查询、可以使使用索引排序或者分组的查询。+ F  P0 ?# ^  o
    7 x) P9 N# Z; p* k6 c, |
    explain select * from user group by addr_id
    $ ]5 H# |  H3 U/ q
    - I- G% Y" s7 ]4 \/ w) o% {
    6 S. n/ }3 h8 @8 i7 T- j; w5 Z/ W, q: J( u7 H
    16.png
    6 s) r* v! y3 Y6 }% a. c8 q) Y5 V! i9 E- m) T, Y7 I* S
    explain select addr_id from user6 i. |+ j! s( F5 j9 h4 y
    4 }& |9 x- F7 u6 P/ S4 Y
    17.png
    2 i+ Q1 V5 t' H
      S* I0 ~7 R9 E8 U) F3 p: q* j4 l. `3 W! A0 u1 O
    4、10 all1 L0 P9 D+ }2 Q. S9 e: j; t
    这个就是全表扫描数据文件,然后再在server层进行过滤返回符合要求的记录。3 V) S1 u5 O& l  b6 o! r. H2 x: I
    1 h- p/ p1 b4 h6 P& z
    五、possible_keys/ X- v5 j+ H4 U; Q: g3 u
    1 s1 f5 K) \* G# W$ ?
    此次查询中可能选用的索引,一个或多个
    : w4 W7 d1 C3 j& n) a8 h4 u  D" f- R( S- c2 c# P
    六、key0 \3 W3 |0 N& g% t4 S7 k# r
    查询真正使使用到的索引,select_type为index_merge时,这里可能出现两个以上的索引,其他的select_type这里只会出现一个。
    ( k2 \+ O- h. a/ F$ w' e- U+ `0 J) Q' ]4 S5 g
    七、key_len4 d  K+ n3 [( ]+ w4 q' Y

    * k1 n; i  t9 U9 _: s用于处理查询的索引长度度,如果是单列索引,那就整个索引长度算进去,如果是多列索引,那么查
    & d' `8 Q& H9 R6 {$ W9 `询不一定都能使用到所有的列,具体使用到了多少个列的索引,这里就会计算进去,没有使用到的,这里不会计算进去。留意下这个列的值,算下你的多列索引总长度就知道有没有使用到所有的列了。' _/ {; v; H4 P1 X' x
    另外,key_len只计算where条件用到的索引长度,而排序和分组就算使用到了索引,也不会计算到key_len中。
    * ?' \  I- o. V3 i; T" {explain select id from type_time where name =‘2’ 用到长度303
    4 i* M/ Y, d1 r+ q* u" f+ _
    ! c/ V) t" j8 {" ~; T( ~ 18.png
    $ R: _6 y: J2 n. {% t, I4 Yexplain select id from type_time where name =‘2’ and time in (‘2’,‘3’,‘4’) 用到长度 1071' U# [; X3 ]( m! r* a

    ! n) ~  V. t8 [9 a" u( ? 19.png
    ; p+ y2 X- e$ {; S
    ) v/ A3 C( ]. W8 f9 E八、ref, A, q8 z; c3 H( u
    如果是使用的常数等值查询,这里会显示const
    9 F9 ]* V0 ?# L& c$ \3 E如果是连接查询,被驱动表的执行计划这里会显示驱动表的关联字段
    5 @  V+ ]* |+ A( X如果是条件使用了表达式或者函数,或者条件列发生了内部隐式转换,这里可能显示为func
    7 I9 {6 P  L2 R
    # c  M! T" H" y1 B& [7 w; r9 Q4 Y九、rows: f2 U3 t2 M4 X; {9 |$ G" @
    这里是执行计划中估算的扫描行数,不是精确值(InnoDB不是精确的值,MyISAM是精确的值,主要原因是InnoDB使用了MVCC并发机制)- M5 ?# j6 Y0 Z1 Z4 J& r; W
    9 j( h2 W+ U* [$ q) c+ @
    十、extra2 u; h6 Q1 ^# a# f5 b4 X. D; m% w( Q
    这个列包含不适合在其他列中显示但十分重要的额外的信息,其中比较常见有一些:
      c- y0 U5 D7 e' ]; ~
    $ }% Y1 p. W& a. [. Z. |10、1 using temporary/ m- h6 r5 Y. ]
    表示使用了临时表存储中间结果。, b0 U8 D( `: l2 e% ]: C5 m5 L
    MySQL在对查询结果order by和group by时使用临时表7 I. T% o6 }7 Z6 @7 ^
    临时表可以是内存临时表和磁盘临时表,执行计划中看不出来,需要查看status变量,
    0 R* A* k- `( O0 }+ z4 vused_tmp_table,used_tmp_disk_table才能看出来。( \' o$ w) c) [8 r
    9 M' `8 F# S6 w) `5 B
    explain select * from user u inner join taddr t on u.addr_id=t.id GROUP BY t.id
    ! q. l! C% o2 v& l# r$ U1 D5 C1 T' L6 }( F$ l! t
    20.png
    0 Y* U7 I; O" W% I
    2 D: F" y* m/ U- I* y+ [8 ?10、2 using filesort  C* p2 Q/ d5 p0 f# f" j
    排序时无法使用到索引时,就会出现这个。常用于order by和group by语句中; K/ ^0 O; f0 b1 ^% n9 V8 i( @

    9 B4 ~. }0 C* @4 k说明MySQL会使用个外部的索引排序,而不是按照索引顺序进行读取。; E0 o8 T- @4 j4 f
    MySQL中无法利索引索引完成的排序操作称为“文件排序“7 t$ l2 t  E6 D+ p3 R1 [

    # [: r. c* x6 o$ t( ~* H10、3 using index
    / ]/ ?# B2 r. A查询时不需要回表查询,直接通过索引就可以获取查询的数据。
    ) p& o  N8 m7 a. p9 V% s* }% g表示相应的SELECT查询中使用到了覆盖索引(Covering Index),避免回表访问数据行,效率不$ J. q& T1 n$ B2 U
    错。+ U5 a$ d4 g& M. F4 }) z; n
    如果同时出现Using Where ,说明索引被用来执行查找索引键值
    ( U  `  F+ Y9 n5 I) Q* t  @* L3 O# ~如果没有同时出现Using Where ,表明索引用来读取数据来执行查找动作。* F! W8 }# ?$ `  O( }1 q# w$ s4 _
    % z8 W' K9 b( T: c, [
    这里对索引的原理和explain做了一些介绍,需要索引需要建立之后对其改变查询方式可能会更能深刻理解 InnoDB 使用覆盖索引和非覆盖索引造成区别。这也是建立索引和使用sql需要特别考虑的问题。* x" @3 z: t) p2 I& @! n+ e
    ————————————————
    3 x4 b2 X5 X0 ]: s1 A1 S- T版权声明:本文为CSDN博主「筏镜」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。' R% M, ^" W( X
    原文链接:https://blog.csdn.net/fajing_feiyue/article/details/105616629- ^0 z: h$ w' Q& Z4 i% z. d
    2 N* \+ Y  y6 r2 s! g
    ) r$ v) ]6 N' @1 B

    20.png (13.61 KB, 下载次数: 426)

    20.png

    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-7-27 13:22 , Processed in 0.462737 second(s), 54 queries .

    回顶部