QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1725|回复: 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

    ) \% z+ z& a2 u0 b$ H, ~8 l  hmysql索引和explain的详解索引原理分析
    3 g3 i! {! w% W) O" I1 J- D
    " b, B" x, i2 P; ^* _索引存储结构
    3 f; m1 q6 U3 B* ]/ t1 G, V3 x索引是在存储引擎中实现的,也就是说不同的存储引擎,会使使用不同的索引1 U' t6 I* e6 ^( z8 {* f4 p$ {' X& W( l
    MyISAM和InnoDB存储引擎:只支持B+ TREE索引, 也不能够更换
    # _. f4 F$ h& S# HMEMORY/HEAP存储引擎:支持HASH和BTREE索引4 t- e! D, _6 z4 u0 X1 Z& E

    ! K9 ?3 v$ K3 s  j- I) MB树图示! [0 h: }* d( h; L. s
      b# o7 T4 i& b) C: ~) p
    B树是为了磁盘或其它存储设备设计的一种多叉(下面你会看到,相对于二叉,B树每个内结点有多个分支,即多叉)平衡查找树。 多叉平衡。3 T& k0 d' `; g* o* V& P+ y

    4 C0 s% z( G4 P; ` 1.png
    , o. @% e% s  k9 Z3 I# x
    $ K' [* `0 T1 M0 w4 R8 z
    3 s' _. O: ~9 B/ Q0 s0 hB树和B+树的区别:4 Y" Y2 K2 J! E4 o
    B树和B+树的最大区别在于非叶子节点是否存储数据的问题
    ) G( d5 a) p8 }1 y) u
    5 \9 w9 ~1 g/ l5 X在结构上:7 Z7 `1 Q3 ]8 s6 t* t- [* f4 @
    (1) B树是非也只节点和叶子节点都会存储数据。
    2 `5 D1 J8 k0 E% t(2) B+树只有叶子节点才会存储数据,而且数据都是在一行上,而且这些数据都是指针指向的,也是有顺序的。4 O) d( Z1 {/ x- n! O) F! n
    2 @7 {9 q7 h( B1 T/ N
    在性能上:( A% _7 u# J  G$ I3 U
    (1)对于B-树相对于B+数据,B-Tree因为非叶子结点也保存具体数据,所以在查找某个关键字的时候找到即可返回。而B+Tree所有的数据都在叶子结点,每次查找都得到叶子结点。所以在同样高度的B-Tree和B+Tree中,B-Tree查找某个关键字的效率更高。B-Tree在单条数据读写有着更强的性能。( b. o8 Y2 g% O% c& P! H
    (2)但由于B+Tree所有的数据都在叶子结点,并且结点之间有指针连接,在找大于某个关键字或者小于某个关键字的数据的时候,B+Tree只需要找到该关键字然后沿着链表遍历就可以了,而B-Tree还需要遍历该关键字结点的根结点去搜索。这个也决定当连表查询的时候mysql比起mongo有显著的优势。更重要的是由于B-Tree的每个结点(这里的结点可以理解为一个数据页)都存储主键+实际数据,而B+Tree非叶子结点只存储关键字信息,而每个页的大小有限是有限的,所以同一页能存储的B-Tree的数据会比B+Tree存储的更少。这样同样总量的数据,B-Tree的深度会更大,增大查询时的磁盘I/O次数,进而影响查询效率。
    " O5 W( |/ }2 k, [4 D6 C9 [
    / I( g6 a/ `4 z! R聚集索引(MyISAM)
    6 d- U( `' z" V( J" T. TB+树叶节点只会存储数据行(数据文件)的指针,简单来说数据和索引不在一起,就是聚集
    % h% n2 O( {4 c索引。$ y' ]% z% P7 s0 T: C* _" m: f: E: `
    聚集索引包含主键索引和辅助索引都会存储数据指针的值。
      Y8 f7 ]' [8 y/ h+ I9 R6 L* ~% ~* o  G
    2.png * k% Z2 D4 R% l6 `# y
      H  F" |" n4 d9 P' ^$ P
    辅助索引(次要索引)
      Q$ n* _- p$ k: q9 W% k/ t; v在 MyISAM 中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求 key 是唯一的,
    - o5 c& i$ B2 C" A1 A2 k: V而辅助索引的 key 可以重复。如果我们在 Col2 上建立一个辅助索引,则此索引的结构如下图所示# S0 A$ x9 F0 Z) ~7 c
    3.png
    - K, L2 ~: N& R" K( u8 Y同样也是一颗 B+Tree,叶子节点中保存数据记录的地址。因此,MyISAM 中索引检索的算法为首先按照B+Tree 搜索算法搜索索引,如果指定的 Key 存在,则取出其data 域的值,然后以 data 域的值为地址,读取相应数据记录。
    7 |4 p" n! T, q6 b7 V
    ; W" S2 \- a5 ?# \8 x聚集索引(InnoDB)- m' y0 \8 q7 o
    1 o6 o0 H5 s# |, N, h
    主键索引(聚集索引)的叶子节点会存储数据行,也就是说数据和索引是在一起,这就是聚集索引。
    , N3 C0 P2 [5 o6 B辅助索引只会存储主键值* ~- W" t! U: J8 x! P& p8 f& E) {
    如果没有没有主键,则使用唯一索引建立聚集索引;如果没有唯一索引,MySQL会按照一定规则创建聚集索引。/ q, q2 A' u: |" x

    ) g6 Y8 }% G" Z! g7 B主键索引' T' q: l, W+ g  G' F- m: R0 W# \
    1.InnoDB 要求表必须有主键(MyISAM 可以没有),如果没有显式指定,则 MySQL系统会自动选择一个可以( n2 \( X6 B# G
    唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL 自动为 InnoDB 表生成一个隐含字段作为主键,类型为长整形。1 q8 @8 r" I, i) h- t" b

    / O, i* V8 \. o1 F- ~4 u* w) K 4.png
    7 _% N* Y" U. Q/ q# C4 P1 }  U. d6 W- S

    ' m) g+ J' f& y: _8 Q; y上图是 InnoDB 主索引(同时也是数据文件)的示意图,可以看到叶节点包含了完整的数据记录。这种索引叫做聚集索引。因为 InnoDB 的数据文件本身要按主键聚集。
    % e1 G/ _" S3 j. p( y 5.png $ `( J0 l4 h5 }% j; z' v0 M. w
    : h5 z3 a: l) H, G2 D! b
    , M) p- ~1 f% j4 T8 v3 d  M4 t+ ~
    6.png
    5 p: x. p8 x9 t- E, ^, n# ?
    & P- r* \# q. U  [0 T* y& r+ ]7 \+ J4 b7 n- S( p' r2 B
    mysql创建索引的时候和用法与索引息息相关,要建立合适的索引和理解一些索引的执行计划,就需要认识索引的结构。" |. }0 `7 T" F8 b" Y, _) m& s

    ( e- `% W) d' R# i2 vexplain的详解
    ' @# `: O0 E/ Y+ E- p! q  J: z- h; f/ \; U# k2 V- p
    参数说明:
    1 g, h  O! Y0 D' F, vexplain后会出现十列数据,下面将介绍这下面的十列数据。
    ) i- x" [0 W+ h* b; B! E
    9 J' F; j7 H, B' Hid、select_type、table、type、possible_keys、key、key_len、ref、rows、Extra/ x% X: V- v1 V! U  ^) i6 _( s

    4 T# D0 b+ O0 b# j, i7 a2 R5 i/ q! J先附上案例表:2 G" r1 i8 \! l; ~" L
    / w# z% `! F2 _: z! ~& w) x
    CREATE TABLE `taddr` (
    ! r  Z) i, R4 ?4 w5 n: c  `id` int(11) NOT NULL AUTO_INCREMENT,! L, Z7 l- z( S1 X" J
      `country` varchar(100) DEFAULT '',9 H' N3 J" k2 d) X- C& ^7 L
      `province` varchar(100) DEFAULT '',
    9 A7 o9 {1 J) y  E6 _  PRIMARY KEY (`id`)+ n9 p; r( E9 Z5 ?& K/ }9 U
    ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
    - ^7 k9 Q' w8 p0 J1 q; [; y$ K
    9 `+ r# B7 r: Y8 |7 t. qCREATE TABLE `user`  (
    + r/ {/ b/ j2 K1 G  `id` int(11) NOT NULL AUTO_INCREMENT,
    0 F. t) D) R" ?3 Y- [  V  `username` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
    ; H9 f, A  d; G4 j5 u0 S. z  `password` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,# i7 n( X, D( b- j- t" s0 c
      `name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,/ f/ l; `' {9 n9 b
      `addr_id` int(11) NULL DEFAULT NULL,# X" a! \" s2 B9 {8 N
      PRIMARY KEY (`id`) USING BTREE,
    ( \8 `7 a% f9 D: D: Z# W  u! L6 e  INDEX `addr_id`(`addr_id`) USING BTREE; w2 \) c/ F9 [9 L
    ) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
    : {. B; h2 t" n5 x9 D' X
    - K( h: ]3 R( E1 g
    # k5 _2 K: k9 m( H$ CCREATE TABLE `type_time` (  |* l+ Z9 U! O' s' o" L4 n$ |+ y- W# g
      `id` int(11) NOT NULL AUTO_INCREMENT,
    ) P# {0 k9 ~: t* D& l- Z, k' p3 M  `time` varchar(255) DEFAULT '[]',
    2 Q+ _6 u' m& D3 e) w# t# y  `name` varchar(100) DEFAULT '',
    " O5 O8 Q$ c1 @# X+ h, u  PRIMARY KEY (`id`),
    0 y9 \" O- b: s( }' A0 h- o  INDEX `name_time_index`(`name`,`time`) USING BTREE' ^2 N( X! @% O( a4 G8 J) K
    ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf83 N7 m5 A. e# g/ W( b
    * @+ P1 y& |" ~6 R$ Y
    一、id% Q0 e$ j) L( G; `  v
    每个 SELECT语句都会自动分配的一个唯一标识符.
    2 P; U% q! R/ Y- x表示查询中操作表的顺序,有三种情况:
    ) F) S2 }/ t; }! t& Y3 F# Oid相同:执行顺序由上到下
    ! w; `6 y4 ~5 \5 Zid不同:如果是子查询,id号会自增,id越大,优先级越高。
    ; \! P9 ~+ p) \$ Did相同的不同的同时存在: P( G' W9 R5 k
    id列为null的就表示这是一个结果集,不需要使用它来进行查询。
      q& R2 R1 k; j! O" R: P& H  J
    0 k4 N3 ~* ^% D3 ]7 c; s0 C# `二、select_type' {& j$ ~5 [- g+ ^3 f

    6 A6 b- z; o  ^) y/ t4 U查询类型,主要用于区别普通查询、联合查询(union、union all)、子查询等复杂查询5 H$ S+ ?4 D9 f2 `

    ' k# Y; G/ l* p4 h5 c. f2.1、simple
    4 U: n+ Z& S! o( ?" X3 {: E表示不需要union操作或者不包含子查询的简单select查询。有连接查询时,外层的查询为simple8 k2 l9 Q' G0 d
    # S0 j4 c( ]) {) |1 r( _
    EXPLAIN select * from user/ e  r: j3 f# N% B

    % B( o4 i0 n  b8 K& D 7.png
    " \. ?1 U" y1 Q4 Q
    1 r2 D' t/ F6 b9 e- X( d# g% ~EXPLAIN select u.id,u.addr_id,a.* from user u inner join taddr a on u.addr_id=a.id
    3 X2 O% K% e& E0 d3 F 9.png
    6 j; W0 ~' q  E+ p9 g
    5 }/ x* |2 \3 @7 {( @  f2.2 primary$ Y' E) c% `  t+ M3 w( o
    一个需要union操作或者含有子查询的select,位于最外层的单位查询的select_type为primary。3 h( K7 R1 x+ L, a( ^
    7 @+ Z; l, I& r
    explain select * from taddr t inner join (
    4 B; E5 _) O8 \% yselect addr_id from user ) u on t.id=u.addr_id* A7 w  `0 t5 L- T$ a9 h
    10.png
    ! o/ v4 P4 c( }: wexplain select * from user u where u.addr_id =1q! I. f& }) P/ x) _# @  `
    union all1 {9 W4 D1 Z) ~$ i8 w  O) J
    select * from user u where u.addr_id =2
    * P7 w' A! Z" L1 O  ?2 O4 [ 11.png
    % f, A/ J" f- p0 c5 a
    ) u* R2 Z, P8 |' ?2 a2.3 subquery! q( p% b& V, R- m9 v0 c
    除了from字句中包含的一查询外,其他地方出现的子查询都可能是subquery& X. s% ?7 ^6 y: O9 U2 l6 b
    5 \, R  W9 y" \; Q
    2.4 dependent subquery
    / w; C  p4 E$ V) R% P/ M6 u9 u
    与dependent union类似,表示这个subquery的查询要受到外部表查询的影响6 ~/ V" A$ o/ W! A- c
    ; p4 h! F& A& h4 C
    explain select u.name,(select t.province from taddr t where u.addr_id=t.id) from user u
    2 R  ], O, g: }) i8 B( d, L: i 12.png
    3 X+ V. I9 o0 E+ a6 w3 r% D2.5 union
    ; [# R/ b) Y9 r  l7 tunion连接的两个select查询,第⼀个查询是PRIMARY,除了第一个表外,第二个以后的表select_type都是union
    8 c5 q+ H4 Y+ p  v/ o/ t; s4 D' W6 n6 F; V
    三、table
    ' w9 [/ T& }) a0 [. P: Y9 P( ^& F显示的查询表名,如果查询使用了别名,那么这里显示的是别名1 Q2 f2 K$ o1 V% W+ B
    如果不涉及对数据表的操作,那么这显示为null! j  H6 t" |1 ~) h8 j6 u0 A
    如果显示为尖括号括起来的就表示这个是临时表,后边的N就是执行计划中的id,表示结果来自于这个查询产生。- H% `" b8 \: M' e
    如果是尖括号括起来的<union M,N>,与类似,也是一个临时表,表示这个结果来自于union查询的id为M,N的结果集。& V1 C) R7 E+ L( Q, k  {' b' N

    * k; n5 K) S7 N5 N$ l* h' i四、type& ]1 T2 c0 x2 Q% p
    ) H) b  g" l3 v/ Z6 b
    依次从好到差:
    3 h/ ?1 W" [. e* Esystem,const,eq_ref,ref,fulltext,ref_or_null,unique_subquery,! ~9 |, U9 A$ Q3 n9 a* ^
    index_subquery,range,index_merge,index,ALL
    % T( r' m3 a! {8 k7 a" z/ _5 S# F7 E3 d  g9 i( v3 O
    除了all之外,其他的type都可以使⽤到索引,除了index_merge之外,其他的type只可以用到一个索引
    1 c  A( \5 d# [7 v2 j
    - q+ a/ a* i$ l" |% c4、1 system
    0 E2 C# @" K9 \+ I  p2 p) B! Q表中只有一行数据或者是空表。% l! y$ d: d! [

    ! X1 }* D( g4 M) x6 u" v9 @4、2const
    ! K3 _. ]) f* L5 T+ K/ A. R* `使用唯一索引或者主键,返回记录一定是1行记录的等值where条件时,通常type是const。其他数据库也叫做唯一索引扫描。8 L7 l* Z5 d( a/ C1 X3 a
    7 ]& h3 k/ V* m8 X
    4、3 eq_ref
    ; W# \5 r- O1 q! N2 n关键字:连接字段主键或者唯一性索引。
    ) a2 M4 @1 e& V+ B6 x此类型通常出现在多表的 join 查询, 表示对于前表的每一个结果, 都只能匹配到后表的一行结果. 并且查询的比较较操作通常是 ‘=’, 查询效率较高.
    . W! a- P( y2 A/ W8 Z" E. {5 }. G$ G! W  G- \) b: V# x2 O6 e- o) r
    EXPLAIN select u.id,u.addr_id,a.* from user u inner join taddr a on u.addr_id=a.id' V3 }- c& A# o. i; R; w; Y2 i! ~

    ) ?" c) p4 f* N, _, v3 h; z( ?3 k3 X1 j5 q3 K" ]1 V; @4 }
    13.png # M1 n6 c% T4 h- f1 y0 L, g
    # _8 ^& P1 r- V
    ) w! b1 u/ Y9 ^9 n- A# f

    4、4 ref
    ! @) w, U) g, n: K5 N' s( X针对非唯一性索引,使用等值(=)查询非主键。或者是使用了最左前缀规则索引的查询。

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

    14.png
    - q2 b+ L0 A+ j$ _* ?: C% y8 v. T9 L& Y. _9 }' |9 a8 N3 z
    4.5 fulltext
    4 X6 L/ y: X  k) e4 O全文索引检索,要注意,全文索引的优先级很高,若全高索引和普通索引同时存在时,mysql不管代价,优先选择使用全文索引
    + U" ~) t/ X( j8 v7 J/ @% B9 w- A- P4 I( w( l  \% E/ K
    4、6 unique_subquery  ?4 d' \2 F6 _$ ]$ _; b
    用于where中的in形式子查询,子查询返回不重复值唯一值
    ) \3 K3 k6 h' H! q+ A1 S  x
    6 B+ Y. |! y3 J( r0 ]4、7 index_subquery: O2 C2 I3 l- O7 W4 `) `
    用于in形式子查询使用到了辅助索引或者in常数列表,子查询可能返回重复值,可以使用索引将子查询去重。3 k3 c7 `- v( c! N$ Y3 x8 u! A9 r

    - g0 ?" }- l% H7 t4、8 range
    $ M  v4 i% J- e9 W" l+ q索引范围扫描,常用于使用>,<,is null,between ,in ,like等运算符的查询中。
    , H( Z& q( D7 M1 E  V3 H
    * n2 H5 k: ?* P0 }" L3 ?explain select * from type_time a inner join (
    / ~- R8 r- g+ {- Qselect id from type_time where name =‘2’ and time in (‘2’,‘3’,‘4’) ) b on a.id=b.id
    ( _+ j$ l( D& n* u! u' p5 p
    & k$ B+ J3 s* F* k9 N: p+ c$ h
    , ~$ f. j* z0 z) E* C6 ` 15.png 5 }  ^1 A8 o3 n/ e- B
    & j; d0 w0 B4 {* L* a( J& |2 q
    4、9 index
    ) u+ a  ^9 C0 L* A: d5 _键字:条件是出现在索引树中的节点的。可能没有完全匹配索引。
    ! s2 b& H9 p  N/ y* f: w9 j索引全表扫描,把索引从头到尾扫一遍,常用于使用索引列就可以处理不需要读取数据文件的查询、可以使使用索引排序或者分组的查询。
    6 B4 a) I$ c  A8 j0 K9 Y' c7 T
    " _5 o/ L* X9 K, Fexplain select * from user group by addr_id; l* f4 f" ]0 t
    : {( v5 G% G& V9 Y

    ' t' [; ?* p8 m! `* M) e; t: p  w  }- K1 O- p9 ?' e
    16.png . y+ A7 Y: Y7 _8 X' e

    " u6 X5 x/ x: k, l) I/ C& @explain select addr_id from user
    , z# q  i) P0 A% w
    + s! [% j) C  ~2 b1 C 17.png - d& Y2 ?6 X7 A$ y# v

    5 ~' J5 X0 U- k! H! _/ H* M, k' H' x4 n' L
    4、10 all
    6 _6 i* J# x' R; o$ r这个就是全表扫描数据文件,然后再在server层进行过滤返回符合要求的记录。
    9 t0 G( N0 a' }! a& p$ P8 n8 c% A$ x* ?( ]
    五、possible_keys. Y# N" @0 K8 I: B  n+ i9 u

    7 `$ A- l$ k/ {& P7 p此次查询中可能选用的索引,一个或多个( [; h5 ~. ~& z+ s7 @" f

    9 g5 ~% w2 N7 p+ [3 v) X0 S六、key. y8 ^3 \" l$ R5 V: N% a* \
    查询真正使使用到的索引,select_type为index_merge时,这里可能出现两个以上的索引,其他的select_type这里只会出现一个。
    - H' I9 ?: `3 g$ V
    + j' e( f0 U4 f8 g- b8 z" u% r& v七、key_len
    9 l1 `) M) }- S/ w+ w+ O& P8 W% v7 s
    8 R( ?" Z" D' x用于处理查询的索引长度度,如果是单列索引,那就整个索引长度算进去,如果是多列索引,那么查
    0 S' u6 n* {; U* J5 P询不一定都能使用到所有的列,具体使用到了多少个列的索引,这里就会计算进去,没有使用到的,这里不会计算进去。留意下这个列的值,算下你的多列索引总长度就知道有没有使用到所有的列了。7 w! c% N. D+ [3 @& Q4 z
    另外,key_len只计算where条件用到的索引长度,而排序和分组就算使用到了索引,也不会计算到key_len中。
    ' N7 L1 k: Z' \explain select id from type_time where name =‘2’ 用到长度303
    8 C) x3 T4 c, Z3 @: m  y' p* y# ~: Y% Q+ p+ X& a
    18.png
    , n, U7 y+ i+ n6 ^7 E8 ?' mexplain select id from type_time where name =‘2’ and time in (‘2’,‘3’,‘4’) 用到长度 1071
    6 n0 x' n" T$ m" P& J$ y# `# _, I5 R5 Z/ j8 K
    19.png " k9 c6 \1 W. G( p

    ( `# S. E: v+ M0 D, x& X# v八、ref
    % c; f6 z! c) K) e2 W" l如果是使用的常数等值查询,这里会显示const
    5 z9 E, M' ]; V& {+ \如果是连接查询,被驱动表的执行计划这里会显示驱动表的关联字段
    8 Y" F' ~8 u$ p, V: ]: S) L如果是条件使用了表达式或者函数,或者条件列发生了内部隐式转换,这里可能显示为func# }( f2 [: |; F
    1 Y. D# x) `; h2 n4 i
    九、rows9 _6 X. I4 f! [+ F; J2 ?2 A1 i
    这里是执行计划中估算的扫描行数,不是精确值(InnoDB不是精确的值,MyISAM是精确的值,主要原因是InnoDB使用了MVCC并发机制)
    7 y5 i$ r2 |& z; E( X
    2 Q# F: j4 j: ]; w& t十、extra8 U& H3 w9 T, q( A
    这个列包含不适合在其他列中显示但十分重要的额外的信息,其中比较常见有一些:
    ; Y, \6 H0 b$ l- w2 G
    $ e, T, H" p3 u4 A( z" @10、1 using temporary. H! Y, W" m8 r- a
    表示使用了临时表存储中间结果。5 T" T  }/ I( \5 d& [7 b8 D
    MySQL在对查询结果order by和group by时使用临时表
    & ^+ `; N+ _& Z- ~临时表可以是内存临时表和磁盘临时表,执行计划中看不出来,需要查看status变量,2 B2 C+ W4 T; U
    used_tmp_table,used_tmp_disk_table才能看出来。4 R& v( U# x8 r& z+ ~2 K
    5 R) m1 |: \1 \6 X; v
    explain select * from user u inner join taddr t on u.addr_id=t.id GROUP BY t.id
    * g3 K( [# {3 V; h7 g7 }+ h' v
    : U; a" S$ r& o! G 20.png
    9 m1 h/ [& b( ]3 }7 y% L& Z) E/ O2 ]
    10、2 using filesort
    - |/ y& n) K' X, |$ E! h3 ~  f排序时无法使用到索引时,就会出现这个。常用于order by和group by语句中
    " T4 k  ?4 [4 K, I5 _7 ]! P: W8 i8 m8 o$ M& y$ V' q: y1 I
    说明MySQL会使用个外部的索引排序,而不是按照索引顺序进行读取。
    ( w# R- |' _! q5 ~( @MySQL中无法利索引索引完成的排序操作称为“文件排序“; d5 j7 L; v. Y: Q$ G+ T" P
    * q1 r% F. V6 Y
    10、3 using index1 E# ^' _" t* t( \
    查询时不需要回表查询,直接通过索引就可以获取查询的数据。
    9 C9 U& O  b% M9 A6 s, F表示相应的SELECT查询中使用到了覆盖索引(Covering Index),避免回表访问数据行,效率不
    # V3 x9 }6 o, a( R9 I4 T错。* v0 V' P) z. [" @% d; O
    如果同时出现Using Where ,说明索引被用来执行查找索引键值
    : r: Q, x3 |9 c0 J; \2 ~如果没有同时出现Using Where ,表明索引用来读取数据来执行查找动作。2 ~7 Q) k& e* L$ [  i
    5 f3 w" ]$ d6 w# t
    这里对索引的原理和explain做了一些介绍,需要索引需要建立之后对其改变查询方式可能会更能深刻理解 InnoDB 使用覆盖索引和非覆盖索引造成区别。这也是建立索引和使用sql需要特别考虑的问题。
    / a2 r6 a3 [9 e+ ~————————————————/ O$ }% ]& I6 [$ r
    版权声明:本文为CSDN博主「筏镜」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。9 c, G6 s4 M! R  ?! T6 v0 r$ F
    原文链接:https://blog.csdn.net/fajing_feiyue/article/details/105616629
    $ S% F9 H0 I$ C- o* I( r: F$ S* }

    5 w. L* z% y9 C* @, v0 Q  w, Y

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

    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-28 01:18 , Processed in 0.430208 second(s), 54 queries .

    回顶部