QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1699|回复: 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
    $ t: ~& p6 R: P9 W& d) a% l
    mysql索引和explain的详解索引原理分析
    + d. y6 B8 S4 J% T2 V
    ( C* u" t  v4 U0 F0 C! }索引存储结构
    $ z- z1 c" C$ T* F5 ?  x8 N% @  x" I索引是在存储引擎中实现的,也就是说不同的存储引擎,会使使用不同的索引
    8 a$ v  i! k! @+ ]' eMyISAM和InnoDB存储引擎:只支持B+ TREE索引, 也不能够更换
    * l, |& b6 O# x. P) HMEMORY/HEAP存储引擎:支持HASH和BTREE索引
    " n7 \1 O1 l8 b" R! [  z$ A
    4 `  C( n( K9 eB树图示
    1 d- a7 a: E9 N" \1 s7 ]" p: r, v, ~' O) b( n
    B树是为了磁盘或其它存储设备设计的一种多叉(下面你会看到,相对于二叉,B树每个内结点有多个分支,即多叉)平衡查找树。 多叉平衡。
    : f& y& o9 A" ?) _7 H& T* K' Z* h5 T% S
    1.png 3 L7 p3 p5 R$ H2 I

    % |8 ]( m3 X& F4 G; K; W) B, E9 N' o7 [
    B树和B+树的区别:9 j* n( o) X2 B$ z8 k
    B树和B+树的最大区别在于非叶子节点是否存储数据的问题' p( q' P4 ?4 \, ^2 J
    " U3 A0 _6 B; f: A2 N5 o9 E! @- Y( A6 E$ G
    在结构上:* j6 R3 [, P' ~4 r
    (1) B树是非也只节点和叶子节点都会存储数据。! L8 t7 B6 ~$ P
    (2) B+树只有叶子节点才会存储数据,而且数据都是在一行上,而且这些数据都是指针指向的,也是有顺序的。
    + A) M5 |  L1 f& j6 A% ?
    - K. ^$ R) |/ a4 Q) R在性能上:4 p- y1 n$ ^+ e1 k* b5 x
    (1)对于B-树相对于B+数据,B-Tree因为非叶子结点也保存具体数据,所以在查找某个关键字的时候找到即可返回。而B+Tree所有的数据都在叶子结点,每次查找都得到叶子结点。所以在同样高度的B-Tree和B+Tree中,B-Tree查找某个关键字的效率更高。B-Tree在单条数据读写有着更强的性能。
    . @' _0 S% [5 e) D0 Y6 t(2)但由于B+Tree所有的数据都在叶子结点,并且结点之间有指针连接,在找大于某个关键字或者小于某个关键字的数据的时候,B+Tree只需要找到该关键字然后沿着链表遍历就可以了,而B-Tree还需要遍历该关键字结点的根结点去搜索。这个也决定当连表查询的时候mysql比起mongo有显著的优势。更重要的是由于B-Tree的每个结点(这里的结点可以理解为一个数据页)都存储主键+实际数据,而B+Tree非叶子结点只存储关键字信息,而每个页的大小有限是有限的,所以同一页能存储的B-Tree的数据会比B+Tree存储的更少。这样同样总量的数据,B-Tree的深度会更大,增大查询时的磁盘I/O次数,进而影响查询效率。5 y/ _! j, y$ y2 z0 q8 h4 `1 G

    . D; o" x# `. \( O' Y' o$ o聚集索引(MyISAM)
    ( ~6 Q; g0 ^( w- M! b% p9 B7 aB+树叶节点只会存储数据行(数据文件)的指针,简单来说数据和索引不在一起,就是聚集# |; ?4 W; ]0 I3 o; ~
    索引。
    . |8 _; i* d* u9 v1 f% N9 q聚集索引包含主键索引和辅助索引都会存储数据指针的值。" d* r6 x1 Y' t, K# C$ _2 ]
    1 |" {, ^/ E/ N6 R/ n9 ?) L
    2.png
      X" o$ ?2 R. a: a: J" L, {. F
    % K/ |/ A. y3 V* s辅助索引(次要索引)
    6 R- T& I7 k" J# k: Y& ]+ `; y2 U在 MyISAM 中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求 key 是唯一的,
    3 T" ?  M! j% s4 C1 |! B而辅助索引的 key 可以重复。如果我们在 Col2 上建立一个辅助索引,则此索引的结构如下图所示
    , O& \( t" b  [! u' W# y 3.png 3 f4 w1 R+ X) X; g+ T6 m3 D
    同样也是一颗 B+Tree,叶子节点中保存数据记录的地址。因此,MyISAM 中索引检索的算法为首先按照B+Tree 搜索算法搜索索引,如果指定的 Key 存在,则取出其data 域的值,然后以 data 域的值为地址,读取相应数据记录。5 O, n9 n" T) @. t0 `
    3 x+ U' H3 w4 d# K$ R1 ~" H6 v
    聚集索引(InnoDB)6 A& d7 p: g; Y7 o
    6 t# I: o7 Z" J
    主键索引(聚集索引)的叶子节点会存储数据行,也就是说数据和索引是在一起,这就是聚集索引。8 x9 _( U$ V& ]! J
    辅助索引只会存储主键值7 a4 e5 L8 H, o' H! s* f# G4 Z
    如果没有没有主键,则使用唯一索引建立聚集索引;如果没有唯一索引,MySQL会按照一定规则创建聚集索引。: _7 |. w1 A" m: O7 p

    , n: k' r( ~5 P# |! Z  l  \主键索引! i! c: `2 d' \
    1.InnoDB 要求表必须有主键(MyISAM 可以没有),如果没有显式指定,则 MySQL系统会自动选择一个可以. N- `7 \4 Z0 ?- D$ n
    唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL 自动为 InnoDB 表生成一个隐含字段作为主键,类型为长整形。$ r. X# V" @& k5 S

    8 v# s1 ^" r, F1 n% ~ 4.png * E7 _) h' N2 X% `8 L* n
    ( U  M4 P. h4 s! I! Z* Z
    0 @. A8 p) R, D( t2 a2 |+ v8 R
    上图是 InnoDB 主索引(同时也是数据文件)的示意图,可以看到叶节点包含了完整的数据记录。这种索引叫做聚集索引。因为 InnoDB 的数据文件本身要按主键聚集。4 }! B' Y" C/ W0 y# Q! u8 q8 P
    5.png ( @) d1 b0 D+ J; q

    1 O3 z7 L# D* u, q) v4 v4 Q9 U4 Q* g( [- d) x
    6.png
    ! s6 M$ `. C' Y7 a: R" }5 e# M! {& e0 Q9 q( r$ r1 S) I* f

    , V1 a  l9 A0 k2 imysql创建索引的时候和用法与索引息息相关,要建立合适的索引和理解一些索引的执行计划,就需要认识索引的结构。$ ^% t; U8 k9 B

      f' q4 ?  {( {5 E/ cexplain的详解
    # f! u9 K1 i# V4 V+ k5 a
    5 n' D2 Z; W; t5 A# m/ Q* D参数说明:
    0 u8 W# s' o$ D+ Rexplain后会出现十列数据,下面将介绍这下面的十列数据。
      F7 ^9 K9 M' }8 b6 e) r) t# p% S) Z8 Q0 i$ t
    id、select_type、table、type、possible_keys、key、key_len、ref、rows、Extra& s4 N/ W) C- i  f8 V% F4 W% p

    0 O' L7 i+ ?- _8 Y先附上案例表:" S; O3 x8 C1 U

    / B/ M! O, J! E4 ]3 Q: U3 |$ MCREATE TABLE `taddr` (( }1 D' Q9 j' E0 r
      `id` int(11) NOT NULL AUTO_INCREMENT,) r  h+ \( W' |- E
      `country` varchar(100) DEFAULT '',
    $ W0 k  j, K: ]/ W  `province` varchar(100) DEFAULT '',
    , d1 v" V. q+ D5 T' R/ b0 c  PRIMARY KEY (`id`)
    / H0 x  o: _6 _6 c3 a; V* X2 h) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
    9 l0 S+ N8 \9 V( X" S) k0 W" \/ s0 ^" V0 [7 {( k( N
    CREATE TABLE `user`  (
    " ~' P, E% I# s+ v  m, |) W  `id` int(11) NOT NULL AUTO_INCREMENT,
    - D- X% T2 p4 z  `username` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,/ r& K. Y4 e4 H# _
      `password` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,  f* d) T- d; S3 L' d
      `name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
    9 w8 J2 {1 s+ b( e' z  `addr_id` int(11) NULL DEFAULT NULL,8 l1 f0 D, f) p
      PRIMARY KEY (`id`) USING BTREE,+ z+ d+ O! Y# T7 d6 P# k( L  Q7 o
      INDEX `addr_id`(`addr_id`) USING BTREE
    + y; i. k: E8 p3 ?) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
    . A7 h$ w# Q2 H! ?
    0 |- T% ~6 t- a1 l9 K9 b  q+ x! Q5 {! i  E5 ]5 A$ u
    CREATE TABLE `type_time` (( c: {% n; o+ D, U/ T9 V
      `id` int(11) NOT NULL AUTO_INCREMENT,# a, ^" x2 w' G7 _9 {1 O' a1 J; |
      `time` varchar(255) DEFAULT '[]',
    # N3 d) P& a  J  `name` varchar(100) DEFAULT '',0 p% Y9 C1 f1 Z" d+ M) Z+ U
      PRIMARY KEY (`id`),4 T) j) I" ~3 a" c: B/ T8 U# c- q
      INDEX `name_time_index`(`name`,`time`) USING BTREE
    * Z9 b2 m' z* X5 x# U( p  ~* K) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
    0 ~$ x6 `* n1 z: U/ }1 D$ l# ?+ ?% q2 y% v4 f  V+ K
    一、id
    ) h8 |/ b% n  `! z' C- ]每个 SELECT语句都会自动分配的一个唯一标识符.
    ! i0 H( N$ W- q" b表示查询中操作表的顺序,有三种情况:+ V  H# ?. z' X' c; i+ [! H
    id相同:执行顺序由上到下
    8 z# G. Y4 J- Y1 iid不同:如果是子查询,id号会自增,id越大,优先级越高。
    0 a# R$ Z) t. b- Z1 k' Hid相同的不同的同时存在
    " L; o) f1 m2 }id列为null的就表示这是一个结果集,不需要使用它来进行查询。
    " i3 u$ _  {0 g, \& e& H2 q
    , ^2 Y# c# @- a二、select_type
    4 E. b+ _: t& h1 ]
    % `# @, X! [( b* K$ u7 Q0 G+ y查询类型,主要用于区别普通查询、联合查询(union、union all)、子查询等复杂查询
    3 D( {- B( w6 R- ]: v& Z  B
    . ^, r9 S; E9 B9 ?$ Z5 i! o2 Q& W+ r2.1、simple; x8 ]. h* p$ v" H/ D5 T2 `
    表示不需要union操作或者不包含子查询的简单select查询。有连接查询时,外层的查询为simple5 Y5 t: c5 ^4 W. v8 x

    * f( V2 C9 E0 A9 G/ I# V& nEXPLAIN select * from user6 n7 K' x" q% j

    . s* d  S( Q9 s& E 7.png
    7 C9 h; l' ^6 g
    7 g, H4 V; E  S* H4 t. ]EXPLAIN select u.id,u.addr_id,a.* from user u inner join taddr a on u.addr_id=a.id( O) K  w# O) y2 |$ F' O& P; C
    9.png * w: J! ]( P5 ?% I: j. G
    : v$ h5 o' V+ H5 _4 s) F. a
    2.2 primary
    ( ], Y# F* p' \/ c一个需要union操作或者含有子查询的select,位于最外层的单位查询的select_type为primary。$ f. N4 O) p: u" T, ?

    6 s$ J9 ~7 N% t5 @explain select * from taddr t inner join (! z2 ^. E" ?- ^; Z/ Z# {" m: `0 z
    select addr_id from user ) u on t.id=u.addr_id9 J* x  @5 p3 ?1 l! X: v- G- `& k
    10.png   I3 q$ u% x1 f$ G
    explain select * from user u where u.addr_id =1q
    + N- L; H" I& f5 F5 ^" J3 uunion all
    : Y1 }% ]! w, V/ x/ pselect * from user u where u.addr_id =2/ P3 ~  W* Z2 o
    11.png " l! m3 w3 S! K/ \. B6 K8 Z
    * B( |! J7 Y- A0 O: f! _6 M
    2.3 subquery
    2 ?1 I7 u% y2 ?1 G# E除了from字句中包含的一查询外,其他地方出现的子查询都可能是subquery
    7 m9 Q/ u/ j/ w$ ]8 i) G" ~& V  h0 q8 d2 o' v
    2.4 dependent subquery4 X6 u8 N8 a+ u' q1 u7 D
    5 p' A. b/ c6 \8 R- v7 h8 g  E
    与dependent union类似,表示这个subquery的查询要受到外部表查询的影响8 W3 Q1 f$ w/ {+ L( i. B

    ; E5 a- r8 t$ dexplain select u.name,(select t.province from taddr t where u.addr_id=t.id) from user u2 Z& Z3 F' p. W
    12.png
    6 v1 j2 K/ b) [& x! L2.5 union
    ) z- P8 r: I& w" T+ ~1 l9 H% Qunion连接的两个select查询,第⼀个查询是PRIMARY,除了第一个表外,第二个以后的表select_type都是union$ v1 f8 P& J9 v, L3 Z$ ?: C

    8 X6 J; ~3 _4 O! B( d5 I三、table
    $ G9 _- T: m$ T# }0 C7 k显示的查询表名,如果查询使用了别名,那么这里显示的是别名
      e& e# \. O) b/ T8 J, U如果不涉及对数据表的操作,那么这显示为null. k2 Z$ p$ H7 x# G1 a! ?+ ?. }
    如果显示为尖括号括起来的就表示这个是临时表,后边的N就是执行计划中的id,表示结果来自于这个查询产生。
    ; E  O6 G% `; a1 T$ z. C如果是尖括号括起来的<union M,N>,与类似,也是一个临时表,表示这个结果来自于union查询的id为M,N的结果集。
    0 q) |# ]9 }% a3 E- w/ j* H& W6 o$ a; [: Y" m& x2 h; n6 U9 m# t
    四、type& {4 W5 r' N2 Q6 Z
    - `# n  D- a2 @! H+ S+ M- D
    依次从好到差:. M7 Y3 S8 K: T9 I
    system,const,eq_ref,ref,fulltext,ref_or_null,unique_subquery,
    # q. m( p- X; G, H/ _index_subquery,range,index_merge,index,ALL  Z* R( Z* {1 ^  ~- h! b" T# o9 N2 ~: V

    ( i. N! H% j1 F除了all之外,其他的type都可以使⽤到索引,除了index_merge之外,其他的type只可以用到一个索引
    2 r- e, x: i. N" j" \
    8 f; k" w4 J2 k, B2 G8 u& x& X2 B4、1 system, ~% [' m8 R* _5 F2 ^' Z
    表中只有一行数据或者是空表。6 B7 X( q' y, B9 u! `& w
    5 \/ Q4 @, c+ ]8 w0 ?
    4、2const; K3 o5 @; |8 I- u2 T1 D; M
    使用唯一索引或者主键,返回记录一定是1行记录的等值where条件时,通常type是const。其他数据库也叫做唯一索引扫描。) F, a; `  D# _; A6 J: s" m8 J' b  G

    ( A' ]. k3 Q5 f* l4、3 eq_ref; _) o8 s+ K' e$ p! j# {9 E
    关键字:连接字段主键或者唯一性索引。& |7 Q: e' ~/ Z! D
    此类型通常出现在多表的 join 查询, 表示对于前表的每一个结果, 都只能匹配到后表的一行结果. 并且查询的比较较操作通常是 ‘=’, 查询效率较高./ O+ B! a& o7 P) Y
    4 B5 R  [5 q( x2 j. L
    EXPLAIN select u.id,u.addr_id,a.* from user u inner join taddr a on u.addr_id=a.id+ v$ E$ R# f& s8 w
    ) L- d5 a, ?! q
    7 D: ^' @" f! t
    13.png ! ^. t6 j9 w; x3 T

    % s# H1 {' p& h6 M. Y
    ! W5 }3 L9 A4 T0 z7 P* v9 J7 \0 {

    4、4 ref
    2 ^1 d1 t! V7 g5 h针对非唯一性索引,使用等值(=)查询非主键。或者是使用了最左前缀规则索引的查询。

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

    14.png $ a6 h& X8 ]! R) R1 I
    ; m2 b0 h9 F6 f# F" Z% W7 b; S
    4.5 fulltext  C9 y) f- p& }( k0 H1 `
    全文索引检索,要注意,全文索引的优先级很高,若全高索引和普通索引同时存在时,mysql不管代价,优先选择使用全文索引
    8 ~, c: ^& h* A/ ]  b. u7 \
    * e5 c: o5 I+ `  J: \+ `* O4、6 unique_subquery
    9 l9 x3 u5 [7 g( N  `3 `. k2 ^; d用于where中的in形式子查询,子查询返回不重复值唯一值, s! L( D# W- k$ l% ~4 Q

    3 z% Y  h# J6 C% C  `$ e4、7 index_subquery; l( V7 E" y* P8 i! e" y+ @' E5 e! [
    用于in形式子查询使用到了辅助索引或者in常数列表,子查询可能返回重复值,可以使用索引将子查询去重。
    0 T" u- G& a+ i  f" b! f; Z' D
    # i# g" ~# n, U2 v. n6 l3 m4、8 range
    # w/ A5 S* G6 |索引范围扫描,常用于使用>,<,is null,between ,in ,like等运算符的查询中。0 L. ~# w1 i" k3 v
    2 ?7 A5 c1 @! j, j: U
    explain select * from type_time a inner join (/ C  b( I' d6 w" C( I- G
    select id from type_time where name =‘2’ and time in (‘2’,‘3’,‘4’) ) b on a.id=b.id% W3 v! t$ E! u% j6 e

    % |: x" }# Q# K! E
    . O' k+ }6 _7 b  f& t- M9 \ 15.png # n' m& p- W1 x
    - w5 Y& e1 a0 n  N8 J. l- R
    4、9 index
    3 S* i1 i; z- S& F键字:条件是出现在索引树中的节点的。可能没有完全匹配索引。9 M& G! r! l+ }7 w3 c4 M
    索引全表扫描,把索引从头到尾扫一遍,常用于使用索引列就可以处理不需要读取数据文件的查询、可以使使用索引排序或者分组的查询。
    ' K6 i  U3 B5 O. N" G! R" V) u( }' o% i8 H# p% }
    explain select * from user group by addr_id
    * W3 S3 i! ?' h" }3 l/ @7 }. f  R: @8 c9 t1 m. N0 Z
    6 h* Y4 o) S! g" C9 e  q
    & P0 U9 K" `1 {/ h3 r, d
    16.png
    . l. N: h. b3 H$ J, }) E9 @. L, I/ \
    explain select addr_id from user
    0 K/ C9 u2 \1 h
    * J/ K' {& p, x5 Y" v 17.png
    6 y) h1 r$ Y( H% _' n. V1 U! I% l
    " N* u' l7 O( W( J! b
    6 w" d& d5 E& C6 p6 Q: a4、10 all0 B0 Y; A$ }1 k4 N8 n
    这个就是全表扫描数据文件,然后再在server层进行过滤返回符合要求的记录。
    ( l1 H& h; R7 F# s- q: Q8 P* h
    $ b8 t' m+ l' j五、possible_keys7 _( k% g1 ^9 T" ]6 d" ]

    ! s  u0 l3 a, G* \- m2 j此次查询中可能选用的索引,一个或多个( l! M# C" n' b( c4 t

    ! r0 l0 J% o) O' c! m6 `3 c六、key* Y  U* b/ F' }( D# s1 K
    查询真正使使用到的索引,select_type为index_merge时,这里可能出现两个以上的索引,其他的select_type这里只会出现一个。2 v4 f' |8 W7 J  Z: \

    6 c' H0 Z( l; z! U8 n七、key_len
    3 N; X5 x* O* ?/ o5 h/ m
    8 m. t+ G- n- X4 x. D% e7 v用于处理查询的索引长度度,如果是单列索引,那就整个索引长度算进去,如果是多列索引,那么查( T/ {3 [# ~( p: L3 k/ I, S( F
    询不一定都能使用到所有的列,具体使用到了多少个列的索引,这里就会计算进去,没有使用到的,这里不会计算进去。留意下这个列的值,算下你的多列索引总长度就知道有没有使用到所有的列了。
    9 \3 @7 ~: }0 ]! i5 D另外,key_len只计算where条件用到的索引长度,而排序和分组就算使用到了索引,也不会计算到key_len中。
    " G' y- }% G+ H8 @% rexplain select id from type_time where name =‘2’ 用到长度303% y- g" F/ ~, D- h% e( S8 `2 ~! ~

    ' r& o5 v: u5 K" G# R( M 18.png
    4 w$ t* S& q4 _: u( Qexplain select id from type_time where name =‘2’ and time in (‘2’,‘3’,‘4’) 用到长度 1071- j, t$ J0 ?) u0 a1 s9 k; `

    " X; z" [6 p1 M. s% ] 19.png ( z, P0 t; X  j: q; Y
    - v  l8 F' ?. l
    八、ref* G( Z$ h6 j; @
    如果是使用的常数等值查询,这里会显示const& a, X* L6 Z8 @" z+ U
    如果是连接查询,被驱动表的执行计划这里会显示驱动表的关联字段
    5 F, f, f) g4 p+ y如果是条件使用了表达式或者函数,或者条件列发生了内部隐式转换,这里可能显示为func( s7 N) E  a# U& S! T. S7 O  u/ l
    # p8 u9 P' }! _3 ~9 o; ]
    九、rows
    # G' j+ o1 B) E这里是执行计划中估算的扫描行数,不是精确值(InnoDB不是精确的值,MyISAM是精确的值,主要原因是InnoDB使用了MVCC并发机制)
    ! H( x9 V  s5 @, r8 D' I/ X0 R* t) t  u7 e* H! }8 j& d1 O  Q
    十、extra
    ) K) X$ L7 w4 s& v这个列包含不适合在其他列中显示但十分重要的额外的信息,其中比较常见有一些:' C/ |. C1 [. k9 [
    1 f+ p" S3 i" p; g8 A
    10、1 using temporary# y* y  l$ a. f$ u; c& w3 _2 w$ H
    表示使用了临时表存储中间结果。. S8 ?1 b! Q  b; r: I  r/ M
    MySQL在对查询结果order by和group by时使用临时表
    ' Y& z% @7 T) B/ ?1 F临时表可以是内存临时表和磁盘临时表,执行计划中看不出来,需要查看status变量,% h2 Y! H/ p1 ?( G- t( z/ Y) \
    used_tmp_table,used_tmp_disk_table才能看出来。
    " v& J+ i9 m" r6 T* w" _$ f
    - r2 m5 n9 S, C! \$ B0 a6 Z0 Bexplain select * from user u inner join taddr t on u.addr_id=t.id GROUP BY t.id# A8 j* s8 O7 J

    ( }. ~! V& X3 Q$ I 20.png " Q2 R. y9 }; {

    / h7 \, M5 j4 R8 j7 X0 a5 |% |10、2 using filesort; j4 e# O. u" D; _5 {! M6 y
    排序时无法使用到索引时,就会出现这个。常用于order by和group by语句中
    # M0 w9 j& {# B) B5 g
    . `, w- U% x1 }* j说明MySQL会使用个外部的索引排序,而不是按照索引顺序进行读取。
    . D; N* a' E  t, O  U# kMySQL中无法利索引索引完成的排序操作称为“文件排序“) D: Q  {  S5 z5 h* |9 z
    : G  Q5 z; `2 o
    10、3 using index
    ' S- @* j8 l- a9 i+ @查询时不需要回表查询,直接通过索引就可以获取查询的数据。" {' A( }: _( u1 T2 L" D' G
    表示相应的SELECT查询中使用到了覆盖索引(Covering Index),避免回表访问数据行,效率不" P0 L3 i8 h+ I$ x# N4 m1 b/ n
    错。* h$ [/ U1 r0 I5 `
    如果同时出现Using Where ,说明索引被用来执行查找索引键值
    % F) `7 j; ?9 g5 l# S5 j$ Z如果没有同时出现Using Where ,表明索引用来读取数据来执行查找动作。( y- i# U" _1 g: r# v- P# z

    , l- X. o) k$ A" g5 L% C% w这里对索引的原理和explain做了一些介绍,需要索引需要建立之后对其改变查询方式可能会更能深刻理解 InnoDB 使用覆盖索引和非覆盖索引造成区别。这也是建立索引和使用sql需要特别考虑的问题。
    , @$ }: ?: A) i& N# J5 P" \" ]: Q————————————————
      D. R; x, y+ f4 a1 E版权声明:本文为CSDN博主「筏镜」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    , t0 g& D0 X+ M原文链接:https://blog.csdn.net/fajing_feiyue/article/details/1056166298 z* }# Y4 t5 k6 S9 q/ z# l

    1 f6 r: G0 ]; a0 ]. z; \( R* B) O3 h7 X& K

    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 20:04 , Processed in 0.409463 second(s), 53 queries .

    回顶部