QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1698|回复: 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
    - k' ]6 C/ k2 y' F7 ?6 P6 w- R; {
    mysql索引和explain的详解索引原理分析
    $ k0 R" |4 z6 M( Z  A" Y0 u1 \7 T! a
    索引存储结构
    + |+ C* S  w* X3 h& J# j/ M索引是在存储引擎中实现的,也就是说不同的存储引擎,会使使用不同的索引
    * v. Y+ I5 j: e7 HMyISAM和InnoDB存储引擎:只支持B+ TREE索引, 也不能够更换
    + h1 r- q2 \% T7 b% o7 GMEMORY/HEAP存储引擎:支持HASH和BTREE索引6 l+ x/ \9 B7 L3 Z% g
    $ N0 R# ^5 H& U6 {
    B树图示
    + X7 T5 I0 h/ l' w; t
      l' K6 P" W3 A0 g7 \B树是为了磁盘或其它存储设备设计的一种多叉(下面你会看到,相对于二叉,B树每个内结点有多个分支,即多叉)平衡查找树。 多叉平衡。( }+ o/ T/ L: q9 k

    2 x& m0 o# c- a: K& o1 v) ^ 1.png
    0 Z' g# N. B3 |) H
    8 W" e# {& V& }8 a9 y1 C% [# t+ C/ s; c
    B树和B+树的区别:- y9 `2 R+ g, g
    B树和B+树的最大区别在于非叶子节点是否存储数据的问题% ?% }3 j5 e9 m- J2 G

    : t8 D( F* q5 Y在结构上:! }, K9 b! u. W; H* U6 A/ n( w
    (1) B树是非也只节点和叶子节点都会存储数据。
    1 O% ~& j( F' l0 y8 h% K(2) B+树只有叶子节点才会存储数据,而且数据都是在一行上,而且这些数据都是指针指向的,也是有顺序的。
    ; U5 m9 A- r, U
    , U1 @) S8 F! ~! D4 [在性能上:( ^* Y4 r  m# N" S. s
    (1)对于B-树相对于B+数据,B-Tree因为非叶子结点也保存具体数据,所以在查找某个关键字的时候找到即可返回。而B+Tree所有的数据都在叶子结点,每次查找都得到叶子结点。所以在同样高度的B-Tree和B+Tree中,B-Tree查找某个关键字的效率更高。B-Tree在单条数据读写有着更强的性能。
    " Z5 G. J/ v8 }1 }(2)但由于B+Tree所有的数据都在叶子结点,并且结点之间有指针连接,在找大于某个关键字或者小于某个关键字的数据的时候,B+Tree只需要找到该关键字然后沿着链表遍历就可以了,而B-Tree还需要遍历该关键字结点的根结点去搜索。这个也决定当连表查询的时候mysql比起mongo有显著的优势。更重要的是由于B-Tree的每个结点(这里的结点可以理解为一个数据页)都存储主键+实际数据,而B+Tree非叶子结点只存储关键字信息,而每个页的大小有限是有限的,所以同一页能存储的B-Tree的数据会比B+Tree存储的更少。这样同样总量的数据,B-Tree的深度会更大,增大查询时的磁盘I/O次数,进而影响查询效率。
    $ ^+ u# |# w" y! P1 f2 T2 I; n
    / \6 Z5 i+ u; t! a$ n* m聚集索引(MyISAM)
    5 i' I1 E4 x5 CB+树叶节点只会存储数据行(数据文件)的指针,简单来说数据和索引不在一起,就是聚集5 A4 d' O: H) C
    索引。
    + o' E; ]& K3 [1 o聚集索引包含主键索引和辅助索引都会存储数据指针的值。  q  s+ a3 g: h+ [1 X- l' k; ~

    . O  |* z/ n: }  c# H* | 2.png
    . |# }; e3 G2 Z3 x0 L1 `& G% f
    4 {* b. t# m- {辅助索引(次要索引)
    ; p( V3 ~6 p8 [( V2 h, L+ y" v在 MyISAM 中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求 key 是唯一的,
    ' k) s3 o/ M" F0 }/ q" C3 o+ L) L而辅助索引的 key 可以重复。如果我们在 Col2 上建立一个辅助索引,则此索引的结构如下图所示& q+ Y1 s! D+ S! U) @/ b. N1 c" m
    3.png
    " z% S7 P/ V9 S- d$ Y; p' V同样也是一颗 B+Tree,叶子节点中保存数据记录的地址。因此,MyISAM 中索引检索的算法为首先按照B+Tree 搜索算法搜索索引,如果指定的 Key 存在,则取出其data 域的值,然后以 data 域的值为地址,读取相应数据记录。
    % U3 O5 a8 ]7 B* V' {, `- L' Z+ [* u  i% A
    聚集索引(InnoDB)- A: F" @7 Y7 _' J3 ^7 d6 U8 e

    ! |/ C! \! `" `9 |主键索引(聚集索引)的叶子节点会存储数据行,也就是说数据和索引是在一起,这就是聚集索引。
      S1 r( k1 q, W; n  q- I; ~辅助索引只会存储主键值: N3 A5 G, b/ \5 x& o( y+ r% z
    如果没有没有主键,则使用唯一索引建立聚集索引;如果没有唯一索引,MySQL会按照一定规则创建聚集索引。9 w  }  Q2 i; I: ~' |' {

    ; t4 L+ ^" \# |4 e) w9 v主键索引
    9 W$ K4 d7 v( t+ E! u9 ]# m# h! q1.InnoDB 要求表必须有主键(MyISAM 可以没有),如果没有显式指定,则 MySQL系统会自动选择一个可以
    6 O8 Y9 i' j' z3 V! O' K, N: t唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL 自动为 InnoDB 表生成一个隐含字段作为主键,类型为长整形。; ^  I. |0 v9 E1 E

    4 ?5 @7 q$ |. f2 l. L* j 4.png
    & {  |) M: s% F
    : S' a5 [) d  }7 F8 J
    ) L# A, H9 |! x! R6 b8 X' ]0 ]* l# F5 P  e上图是 InnoDB 主索引(同时也是数据文件)的示意图,可以看到叶节点包含了完整的数据记录。这种索引叫做聚集索引。因为 InnoDB 的数据文件本身要按主键聚集。/ o. N' L7 y3 w) x& f( \% @1 `
    5.png
    * y. i5 k* _  Z) y! I6 [* V2 B( h! P0 \" o

    % K* A% J9 m7 B  }& }& Q, ] 6.png
      V  I# ~1 C. X
    " F' P; [/ z7 u0 z! \, y/ P  }5 X! G. t  v! T
    mysql创建索引的时候和用法与索引息息相关,要建立合适的索引和理解一些索引的执行计划,就需要认识索引的结构。+ S% y# u0 D* W( a7 Q
    , Q) Q" V2 f* D$ I. l: q
    explain的详解
    ( }& ?4 _, t2 ~0 \
    * ?5 y4 Z5 @+ M/ d& o, i参数说明:
    : K. W  K: j3 O8 a) vexplain后会出现十列数据,下面将介绍这下面的十列数据。
    ( E4 o' A/ Z1 X9 Y
    3 a; W6 |1 p* ~9 K( i2 b; did、select_type、table、type、possible_keys、key、key_len、ref、rows、Extra
    ) Z$ R* X7 p, h: D9 Z3 A, X* k5 _9 c2 R; y
    先附上案例表:
    , E7 b6 B, R0 ~( M2 d0 k+ d5 u+ u7 q" ~+ Z, \2 @
    CREATE TABLE `taddr` (7 r& ~! u1 }5 ]1 I
      `id` int(11) NOT NULL AUTO_INCREMENT,& F, h+ I# k# o$ X; [
      `country` varchar(100) DEFAULT ''," G! I( D0 {. p4 k- d% W/ Y
      `province` varchar(100) DEFAULT '',: H) _/ a: h  A( _. q
      PRIMARY KEY (`id`)
    5 k% P+ j/ ~% k9 w3 J7 G! T) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
    7 P! E6 l5 S9 h! Q% p2 }- |- ~' x  S# ~! J! w2 G
    CREATE TABLE `user`  (6 R) h! ^  O8 p& h8 a7 E2 ]# f/ ?
      `id` int(11) NOT NULL AUTO_INCREMENT,
    $ A. R$ b0 c9 s7 [9 t4 j  `username` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
    ! h9 ?6 j) z$ L1 j" e( k  `password` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,$ G$ |( I6 ^! [! A1 m- Y" M0 V, L
      `name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,; O6 H9 D/ h+ p& g) H3 q
      `addr_id` int(11) NULL DEFAULT NULL,
    7 s* D5 B2 ?% k7 l: S6 y) f9 K  PRIMARY KEY (`id`) USING BTREE,7 K4 o: c( I0 G
      INDEX `addr_id`(`addr_id`) USING BTREE
    ( q$ }* a+ G9 y# t' F7 S  ?* w! i" w) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
    " N% ]. k" C3 l  A* w; i9 V  t. U1 m# G

    % h7 k1 x1 ^+ U; T9 S5 kCREATE TABLE `type_time` (
    5 E! G$ s2 U" ~) p# ?' Q+ {  `id` int(11) NOT NULL AUTO_INCREMENT,+ {' n; Z+ c3 j' }6 a
      `time` varchar(255) DEFAULT '[]',
    : V; n  \# ?. z* ~4 N" s- c  `name` varchar(100) DEFAULT '',- h) x3 B8 d3 e1 N' c3 }/ W
      PRIMARY KEY (`id`),8 U! G. J  F# f4 p5 h) W- m7 c+ a
      INDEX `name_time_index`(`name`,`time`) USING BTREE: a6 K$ d: y1 C$ H- M4 t% ?
    ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
    1 H8 |/ d) Z" H, `7 t, K3 |% E0 k2 K2 q* y( g. J0 Z3 N2 `
    一、id# [" A. ~7 s9 G  E
    每个 SELECT语句都会自动分配的一个唯一标识符.
    & J# z, [; x2 J4 ~表示查询中操作表的顺序,有三种情况:
    % X  Y+ {9 s" Eid相同:执行顺序由上到下3 \: X" u0 E8 s0 l. e  ], k4 _; K
    id不同:如果是子查询,id号会自增,id越大,优先级越高。
    3 C+ }( C( H+ wid相同的不同的同时存在
    ! Z1 l$ y2 y! w6 k, Gid列为null的就表示这是一个结果集,不需要使用它来进行查询。4 r  |: ^+ G: p" B7 \
    1 Y1 V& @$ C9 O7 f" }3 ]) ?
    二、select_type- }2 T. M( V8 }* a

    ' U  i. E1 B3 w2 S# H查询类型,主要用于区别普通查询、联合查询(union、union all)、子查询等复杂查询3 T; B4 q3 Q7 P  O
    ( n9 B" J6 ^- M2 [  A5 r
    2.1、simple( N0 D3 f. D8 u8 w- N" X
    表示不需要union操作或者不包含子查询的简单select查询。有连接查询时,外层的查询为simple
    # p4 q1 F' q" O7 b& u! s, K
    + K2 f% _, b4 }EXPLAIN select * from user
    5 c5 v% {2 u# L7 N; \
    2 @7 M% ?' u' F# ?+ _$ V, K6 I 7.png 9 [6 M3 e; L" k
    & O. K' ~; @4 Z# N) |* M8 G
    EXPLAIN select u.id,u.addr_id,a.* from user u inner join taddr a on u.addr_id=a.id( v& n& u( k. @. M+ L, C
    9.png
      X  v, W9 R9 w0 D# y: y% [1 u- y; L$ M
    " ]1 p. L0 n3 q/ |' z$ N2.2 primary8 l  O# z" ?. I
    一个需要union操作或者含有子查询的select,位于最外层的单位查询的select_type为primary。
    , \4 B$ I& l3 h/ ?8 s* m9 X' W# j! w  y
    explain select * from taddr t inner join (* Q5 r9 O6 U5 B# H, ]9 N
    select addr_id from user ) u on t.id=u.addr_id6 I9 T1 {0 N6 w0 V8 o8 G
    10.png
      d1 m# c: O- hexplain select * from user u where u.addr_id =1q
    , \7 T" Y& T. `0 Y1 h% d3 t/ iunion all/ I) |6 }! I) _3 f1 O2 J' v0 J
    select * from user u where u.addr_id =28 U0 e- e1 B. g0 @) X- {+ o
    11.png " \1 }# Q- h, d  n) g1 A) \/ z' t
    ) b) c8 l5 ?8 h  H1 l! k. _- P5 R
    2.3 subquery) Y! H3 U- D2 a7 \: M1 p
    除了from字句中包含的一查询外,其他地方出现的子查询都可能是subquery
    1 ~; a: g- o- K9 M" X( a9 k$ Q2 \
    , d) ^. v2 n& F! P2.4 dependent subquery
    7 Z8 a4 d. |: @. ~; g6 }" O7 O9 W9 Z+ n
    与dependent union类似,表示这个subquery的查询要受到外部表查询的影响: Z( y" ]4 y; _5 G0 r
    6 [5 p( n$ E2 O2 m& f9 \: g5 E/ }
    explain select u.name,(select t.province from taddr t where u.addr_id=t.id) from user u) o: N: U, K  W4 F1 L' ]' o7 e
    12.png
    ' t5 G) r- q# l* Z  D  y3 I3 V# J2.5 union- L9 A6 ~. o4 Y8 \5 |$ b
    union连接的两个select查询,第⼀个查询是PRIMARY,除了第一个表外,第二个以后的表select_type都是union3 R: w: U, T+ P3 E" n$ y4 p4 W4 B7 T; t
    / R: H$ ]5 D: q( {) H/ m1 S
    三、table  \# L9 T, n) p2 ~+ R1 W9 {  Y
    显示的查询表名,如果查询使用了别名,那么这里显示的是别名
    ! O6 U. X+ G- \$ C. v如果不涉及对数据表的操作,那么这显示为null4 X3 H3 b! I3 o) _+ x$ ?2 n: R  _& E
    如果显示为尖括号括起来的就表示这个是临时表,后边的N就是执行计划中的id,表示结果来自于这个查询产生。2 X6 ^1 Y! N$ c5 a$ ]
    如果是尖括号括起来的<union M,N>,与类似,也是一个临时表,表示这个结果来自于union查询的id为M,N的结果集。- l  M1 o* L2 e0 A- h  d

    & N# ?- C2 n7 u0 ~9 m0 r3 O四、type( x0 K6 m" }) T2 i

    - U. X) b$ C: g; Q* @, B依次从好到差:- ?1 d, ?2 l6 ~5 s) P
    system,const,eq_ref,ref,fulltext,ref_or_null,unique_subquery,: i9 a1 l# Y) @( L6 U
    index_subquery,range,index_merge,index,ALL/ I; s1 s- u5 Z" F' r
    # K( n# L  Z% G- j. N; I1 p
    除了all之外,其他的type都可以使⽤到索引,除了index_merge之外,其他的type只可以用到一个索引
    * ]5 \6 W( G' l% w1 y0 r3 s' w# b% G; {' a6 F3 `. H+ J5 K
    4、1 system' {% n9 q+ A( F5 p' a
    表中只有一行数据或者是空表。
    2 r( p% }7 a$ S8 C' `6 r4 u  z* P3 u7 r. Z, t, G& d) G4 ~. m
    4、2const) d4 H+ @* a8 A0 P( z: n& G9 C
    使用唯一索引或者主键,返回记录一定是1行记录的等值where条件时,通常type是const。其他数据库也叫做唯一索引扫描。" z* p+ L) e4 z# ]6 s& U8 `

    ) I& {, h) T- G4、3 eq_ref
    , ~! J( ?. b8 }/ Q关键字:连接字段主键或者唯一性索引。; ~& Q; e1 I* A2 T
    此类型通常出现在多表的 join 查询, 表示对于前表的每一个结果, 都只能匹配到后表的一行结果. 并且查询的比较较操作通常是 ‘=’, 查询效率较高.
    4 F. ~2 t" r  }
    / t( Z9 V8 n0 R5 W) p; ?EXPLAIN select u.id,u.addr_id,a.* from user u inner join taddr a on u.addr_id=a.id
    & b8 w! \! ~; A8 D9 C' A6 O3 g% q7 [; @  P
    . l, O. l# Q: X$ M' s
    13.png ( I6 ^# b1 d5 i" ~. B

    & \1 j' Z/ A2 x4 ]; R0 r3 m. E$ W1 k( n/ V

    4、4 ref; N  `5 ]6 F4 o/ v0 Z
    针对非唯一性索引,使用等值(=)查询非主键。或者是使用了最左前缀规则索引的查询。

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

    14.png
    3 t- d% b0 S, [: S; t* Z- K. \: F) h; Z8 ]+ n0 {
    4.5 fulltext
    . f# r6 m1 O8 `全文索引检索,要注意,全文索引的优先级很高,若全高索引和普通索引同时存在时,mysql不管代价,优先选择使用全文索引
    " L- m5 z; C. N% |- F/ R
    $ B7 o: L  o3 v+ `9 o4、6 unique_subquery9 N& O. b" [' l# l
    用于where中的in形式子查询,子查询返回不重复值唯一值) l; k  i7 m  b2 v/ c* `, Y9 K

    ! y; A8 L) T5 r8 W4、7 index_subquery: `2 Z8 P; t+ n5 V
    用于in形式子查询使用到了辅助索引或者in常数列表,子查询可能返回重复值,可以使用索引将子查询去重。
    , w# m* n0 O4 G$ K/ D/ Q0 A6 J
    ( r$ Y' J8 b, s5 X# Z0 C. Y4、8 range
    / @; V7 |3 d! D; ~! @$ n9 d索引范围扫描,常用于使用>,<,is null,between ,in ,like等运算符的查询中。- ^1 F& r/ `0 H8 P& T/ f; _
    8 y3 m+ r/ Q( k. s
    explain select * from type_time a inner join (
    ; ?/ z$ E  m( G5 f3 \0 Y# Q( ?( Rselect id from type_time where name =‘2’ and time in (‘2’,‘3’,‘4’) ) b on a.id=b.id/ u! @( d0 K8 d3 @* P& V, a* O& j* O

    & O7 I$ z! c0 a0 v2 d3 k5 }! C3 n: r$ G/ r( P
    15.png : H" z/ X. K4 ^$ w  e$ A* x" d, _

      k4 ]+ I/ j, U% _; o3 m% t4、9 index
    ' {! W' _0 h* J2 R键字:条件是出现在索引树中的节点的。可能没有完全匹配索引。
    2 J( ]- g6 Y, o$ A1 P! V索引全表扫描,把索引从头到尾扫一遍,常用于使用索引列就可以处理不需要读取数据文件的查询、可以使使用索引排序或者分组的查询。0 z' {4 e: k7 W0 Y+ l

    ; J- a. _+ v: \# u( pexplain select * from user group by addr_id8 T+ F1 X  @8 T8 @% X# P
    & Q9 z8 F( e8 l; q* ]/ n/ M
    3 O3 S: O' G8 n
    0 ^9 u, s( Z9 g, g+ A( E
    16.png
    ' l4 [, H, z" K$ T8 q4 v, Q  e' w* j
    explain select addr_id from user7 C& D% L8 k" J4 U1 r6 [& }
    & O" ]/ j- f' H# B
    17.png 1 m/ l; p5 @/ k2 r& g
    4 c7 |; p7 o3 |: O
    , R$ p5 Q& s- p8 n4 O1 L4 @2 W, r
    4、10 all. ?" _* A2 [; ^7 N4 |
    这个就是全表扫描数据文件,然后再在server层进行过滤返回符合要求的记录。
    # c) @- t: B3 \7 `  Y- p* G% J* b7 l7 i; {- X2 T
    五、possible_keys
    $ L% C( J( n% a: o  U# k
      T, g4 Y% Z0 |6 k* L% z此次查询中可能选用的索引,一个或多个
    ( N- S3 u4 j5 C2 f2 N2 }! d, T& y9 J- O
    六、key5 L0 {  W* |% _  f! B
    查询真正使使用到的索引,select_type为index_merge时,这里可能出现两个以上的索引,其他的select_type这里只会出现一个。: ~1 F* D  n$ g- w  C  J- X

    ) E! ]0 }; c) f; `8 v. \, V' s七、key_len) g8 K* U3 \: M) x& Q
      i  D. }( `7 V6 p; z/ q. t
    用于处理查询的索引长度度,如果是单列索引,那就整个索引长度算进去,如果是多列索引,那么查
    ; c% c- r/ x, g询不一定都能使用到所有的列,具体使用到了多少个列的索引,这里就会计算进去,没有使用到的,这里不会计算进去。留意下这个列的值,算下你的多列索引总长度就知道有没有使用到所有的列了。" B2 {1 ~( T; P
    另外,key_len只计算where条件用到的索引长度,而排序和分组就算使用到了索引,也不会计算到key_len中。5 E) T6 R8 D' f2 h* u) M2 @2 y
    explain select id from type_time where name =‘2’ 用到长度303+ f4 [. o# E/ b% `; E) \
    2 h+ r" v, {; C. d, o# r% L) e4 D3 `
    18.png
    / t0 C! q7 M1 |- e4 Fexplain select id from type_time where name =‘2’ and time in (‘2’,‘3’,‘4’) 用到长度 1071( d% C2 p. U! Q2 f" s5 Z" y

    5 Z* B  `( y! o, X" z4 U* |+ H 19.png
    ! y; G1 _. K. {6 z1 N5 L- ]( p- U6 n& b7 w& a. g: X7 J. G3 t$ [
    八、ref
    6 I& z  o, q( x- w如果是使用的常数等值查询,这里会显示const0 R* W' r; r0 t4 Z
    如果是连接查询,被驱动表的执行计划这里会显示驱动表的关联字段- _# n: \- k. F* _9 C
    如果是条件使用了表达式或者函数,或者条件列发生了内部隐式转换,这里可能显示为func
    " d3 t9 g6 T# J0 @9 E& P* `" k0 z
    九、rows$ {8 h8 Y8 P6 K5 A/ B! A
    这里是执行计划中估算的扫描行数,不是精确值(InnoDB不是精确的值,MyISAM是精确的值,主要原因是InnoDB使用了MVCC并发机制)) x+ n' ^2 w5 l
    * X$ K/ ~5 A2 _; N6 C
    十、extra
    9 X, E: G( w( w; E  Y. }这个列包含不适合在其他列中显示但十分重要的额外的信息,其中比较常见有一些:9 c5 S- W6 u1 R% {  v

    5 u5 `3 ?1 S7 I10、1 using temporary
    1 }7 ?: Q! v* t6 W1 n表示使用了临时表存储中间结果。( W$ \! ]5 @# M$ O% {1 @: J/ n
    MySQL在对查询结果order by和group by时使用临时表9 D: |& U) J, }5 @+ K
    临时表可以是内存临时表和磁盘临时表,执行计划中看不出来,需要查看status变量,0 h+ P; [, O; i, D( C
    used_tmp_table,used_tmp_disk_table才能看出来。
    . h) S% @1 s9 F$ D7 r0 o
    . |' g- @9 ?: y0 ^4 R: q$ zexplain select * from user u inner join taddr t on u.addr_id=t.id GROUP BY t.id( n  f& W' Z! m' `7 U" [
    , Y0 ~/ `; B0 N: N1 h7 H) S
    20.png
    5 o! S  u7 N  K3 ~. G+ W
    5 }9 `3 y, Z& ]6 }( b10、2 using filesort- d2 W/ `6 Q6 q8 u8 b, ^
    排序时无法使用到索引时,就会出现这个。常用于order by和group by语句中
    8 V8 d5 A3 m, N* `% S2 N: H5 ]$ {- w. \3 _  }# m8 E) Z
    说明MySQL会使用个外部的索引排序,而不是按照索引顺序进行读取。8 J5 ?% X% R* B2 T4 T- A
    MySQL中无法利索引索引完成的排序操作称为“文件排序“
    # c' D+ n" S  p" [
    1 N6 B& E& k/ ?5 f# f% X10、3 using index
    1 g( d! j! u  o! p2 N查询时不需要回表查询,直接通过索引就可以获取查询的数据。
    2 J' j, F/ k% u" O表示相应的SELECT查询中使用到了覆盖索引(Covering Index),避免回表访问数据行,效率不* k. ~, ^. r! {5 d7 |  d
    错。5 x: {* f' P" d
    如果同时出现Using Where ,说明索引被用来执行查找索引键值
    % Y) O$ f. V6 I; J) `; d/ y  A如果没有同时出现Using Where ,表明索引用来读取数据来执行查找动作。
    . _- h# J: D% t( G/ k/ F* ?; X% s. F
    * ?$ r0 L/ |0 ^* n% A! |! j$ f( h* s  }这里对索引的原理和explain做了一些介绍,需要索引需要建立之后对其改变查询方式可能会更能深刻理解 InnoDB 使用覆盖索引和非覆盖索引造成区别。这也是建立索引和使用sql需要特别考虑的问题。; s3 V4 g; |4 W/ |; ?# U) Z
    ————————————————9 B# S- x0 w' _( n8 ?( L: \
    版权声明:本文为CSDN博主「筏镜」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
      d& k0 r" d. z) J/ i6 r原文链接:https://blog.csdn.net/fajing_feiyue/article/details/105616629
    4 H( L: G  F% S7 i  M- H
    - J" u# O$ Q1 S+ X0 Y0 {0 k! S; m& m: ]/ D6 G# G9 h! z

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

    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-6-9 18:56 , Processed in 0.459251 second(s), 53 queries .

    回顶部