QQ登录

只需要一步,快速开始

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

    : r% l6 d3 v' h9 jmysql索引和explain的详解索引原理分析
    : {' `2 j2 Q) h8 X; n( F
    ! N' X# }: r, ~索引存储结构9 H5 d1 ?# {9 V' n4 A& v) M8 h/ ]
    索引是在存储引擎中实现的,也就是说不同的存储引擎,会使使用不同的索引
    ' W! @5 s! c, k; C0 c- cMyISAM和InnoDB存储引擎:只支持B+ TREE索引, 也不能够更换0 P9 q( U2 Z% a6 W3 A; `- q8 I$ V
    MEMORY/HEAP存储引擎:支持HASH和BTREE索引* ?1 i1 a# Z# n7 V  |
    . G* a3 G1 x" h+ f
    B树图示
    3 B" S& x; B7 N4 `* L4 \8 j; }; J' h5 s2 k; N
    B树是为了磁盘或其它存储设备设计的一种多叉(下面你会看到,相对于二叉,B树每个内结点有多个分支,即多叉)平衡查找树。 多叉平衡。
    ! B% ]7 |+ C" ^" x
    / z. b# M; m$ `& k  ^2 w 1.png
    + }' E: w4 @4 c5 w3 C/ f% h! E; i( i

    5 E! W- N4 D+ B$ wB树和B+树的区别:
    * `4 K" K  e8 m1 n( i. t6 ~9 TB树和B+树的最大区别在于非叶子节点是否存储数据的问题% i2 a; P% h: G5 x

    - w1 G' R, {4 @* Y" D1 O1 t在结构上:
    7 E& b% I" T4 |4 O; E(1) B树是非也只节点和叶子节点都会存储数据。5 r3 r1 L; {, H  y: |
    (2) B+树只有叶子节点才会存储数据,而且数据都是在一行上,而且这些数据都是指针指向的,也是有顺序的。
    7 i/ }' p8 l8 E6 x! L8 Z
    ' q# b! C5 C+ \3 y7 X8 t在性能上:
    / ]! d" T4 b, y6 |6 J$ ^(1)对于B-树相对于B+数据,B-Tree因为非叶子结点也保存具体数据,所以在查找某个关键字的时候找到即可返回。而B+Tree所有的数据都在叶子结点,每次查找都得到叶子结点。所以在同样高度的B-Tree和B+Tree中,B-Tree查找某个关键字的效率更高。B-Tree在单条数据读写有着更强的性能。
    7 t" ?$ _  Q8 m  p(2)但由于B+Tree所有的数据都在叶子结点,并且结点之间有指针连接,在找大于某个关键字或者小于某个关键字的数据的时候,B+Tree只需要找到该关键字然后沿着链表遍历就可以了,而B-Tree还需要遍历该关键字结点的根结点去搜索。这个也决定当连表查询的时候mysql比起mongo有显著的优势。更重要的是由于B-Tree的每个结点(这里的结点可以理解为一个数据页)都存储主键+实际数据,而B+Tree非叶子结点只存储关键字信息,而每个页的大小有限是有限的,所以同一页能存储的B-Tree的数据会比B+Tree存储的更少。这样同样总量的数据,B-Tree的深度会更大,增大查询时的磁盘I/O次数,进而影响查询效率。
    , z+ W. B5 j! _' Z9 @# m- D- v5 u- f/ Q; e
    聚集索引(MyISAM)" W+ f% J) G& }& F
    B+树叶节点只会存储数据行(数据文件)的指针,简单来说数据和索引不在一起,就是聚集4 i" k  s" w& J' x6 a
    索引。
    : X$ v1 h" I0 Z  ^聚集索引包含主键索引和辅助索引都会存储数据指针的值。
    # T! t- ^! N# Z% {' `' l
    4 H: r& ~/ ^7 q8 t: {6 R 2.png
    - w0 `- d, d2 D8 n
    3 T9 I  Y) b; t  D: q- h# ^* r辅助索引(次要索引)4 s8 R9 z3 J4 P7 R5 R
    在 MyISAM 中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求 key 是唯一的,
    7 j) w% Y3 U* K" p  X2 J% r" Z* a: `而辅助索引的 key 可以重复。如果我们在 Col2 上建立一个辅助索引,则此索引的结构如下图所示
    6 E3 `2 e1 y0 T. J, S: t7 l4 S 3.png + \) x3 w% R5 C9 @+ a5 o# S
    同样也是一颗 B+Tree,叶子节点中保存数据记录的地址。因此,MyISAM 中索引检索的算法为首先按照B+Tree 搜索算法搜索索引,如果指定的 Key 存在,则取出其data 域的值,然后以 data 域的值为地址,读取相应数据记录。/ F# W) S" Y# I9 n

    7 A; R5 ?; P- c- D聚集索引(InnoDB)) n8 f6 D* C8 z9 X. b

    " r0 ^% D/ @( o3 w$ u# A, x9 y主键索引(聚集索引)的叶子节点会存储数据行,也就是说数据和索引是在一起,这就是聚集索引。
    - F- [, C; X; M$ A: ]辅助索引只会存储主键值
    ) k$ Z! m7 ^! R0 ^* J) Q8 K如果没有没有主键,则使用唯一索引建立聚集索引;如果没有唯一索引,MySQL会按照一定规则创建聚集索引。+ g% J) g/ r+ c
    : K6 o% T- L' k4 A' }" r
    主键索引
    8 U% k1 s3 Y* d1.InnoDB 要求表必须有主键(MyISAM 可以没有),如果没有显式指定,则 MySQL系统会自动选择一个可以
    4 e7 j; T3 K, f) B, ?6 y9 M% c/ y唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL 自动为 InnoDB 表生成一个隐含字段作为主键,类型为长整形。
    9 {2 |* y/ U. I1 ]& R8 l+ H* ?1 z( t! _$ S( q9 L. A8 U
    4.png 1 _4 W3 b$ ?7 R0 l

    4 {; R5 `$ x) _" g# B; @. t# v" R, a) |$ r, _
    上图是 InnoDB 主索引(同时也是数据文件)的示意图,可以看到叶节点包含了完整的数据记录。这种索引叫做聚集索引。因为 InnoDB 的数据文件本身要按主键聚集。
    4 \: h, V) L% v' f0 U+ h6 ? 5.png
    0 O+ t& Q3 m$ F, N  _4 _! X) d$ Z7 E: D& x
    / L; v( @) H& o- ^6 B3 J
    6.png ; P) A8 X/ @5 l6 a; Y

    # C: m7 q: n; o/ \/ g0 M( C
    2 ?6 p# y' W5 H3 U. lmysql创建索引的时候和用法与索引息息相关,要建立合适的索引和理解一些索引的执行计划,就需要认识索引的结构。9 e# z8 {! y' o( D
    ! I9 `$ Q1 r4 K! C/ T
    explain的详解6 {4 t; I4 @! g* W: Y+ F& `

    . L* m& E6 b' e2 B0 k. S" ~& F- q参数说明:
    - _5 |* f' S( B& sexplain后会出现十列数据,下面将介绍这下面的十列数据。6 \2 N* n% f7 C8 A3 l* t  E

    - h9 P& O1 u7 Pid、select_type、table、type、possible_keys、key、key_len、ref、rows、Extra9 r! Y$ w( F: A; s+ _" Z+ k, G
    3 U4 Z' y' F9 G' s
    先附上案例表:9 C, n6 U" j9 `$ @1 F# |& D( u

    ; j2 d7 x5 I9 @  k0 m# }CREATE TABLE `taddr` (
    ' H; T4 @( R: j' g' Y* {: ~! X9 o2 p5 _  `id` int(11) NOT NULL AUTO_INCREMENT,( b9 b/ ^/ }. D1 V6 n" b
      `country` varchar(100) DEFAULT '',
    7 ~- |- |4 u5 |/ f& d) E  `province` varchar(100) DEFAULT '',
    " U5 f9 d$ e/ t3 e# o# ?  PRIMARY KEY (`id`)
    ( [1 s* a) ?3 d% m5 R) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
    9 u6 s8 ?2 r5 _  t, e  k$ }- X1 F" l
    CREATE TABLE `user`  (
    3 h& R* m2 t' i: W! P8 L1 I  `id` int(11) NOT NULL AUTO_INCREMENT,  R$ c1 X: ~  y* p& T  n  R
      `username` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
    - v2 \# {. ]; k; ]* }. S  R  `password` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
    : P. y  |8 i) C+ T2 ~% Z  `name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,7 @+ P% h& E( p) f0 G+ t# B) T
      `addr_id` int(11) NULL DEFAULT NULL,& @+ D8 n6 `9 g4 S+ E6 ?
      PRIMARY KEY (`id`) USING BTREE,
    ( k+ O5 ]' E" \' {" {  INDEX `addr_id`(`addr_id`) USING BTREE4 {( E/ V' y) u! m
    ) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;$ N. \# M5 z0 w4 L# @# ^

    & W: A# q9 a/ S# q$ T2 ?" G/ y! T, U2 S8 [1 c
    CREATE TABLE `type_time` (/ \+ g, X+ V/ |% o
      `id` int(11) NOT NULL AUTO_INCREMENT,
      u, i+ X3 P, S, z' G% }" i# \. I+ N  `time` varchar(255) DEFAULT '[]',/ J+ ^- a2 }. S' i4 \) K
      `name` varchar(100) DEFAULT '',; @. E; F0 k) n( n9 L
      PRIMARY KEY (`id`),+ s+ a, Q, x$ W8 \( S$ h% j% g
      INDEX `name_time_index`(`name`,`time`) USING BTREE. U; a5 u2 G! W1 P! V) L/ L' ~
    ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8) E7 P' I) q; y& M) M% w% I% Z. G
    0 S! N+ G8 a9 t9 H/ N; B4 l
    一、id8 Y* o7 j5 y' D& k3 C
    每个 SELECT语句都会自动分配的一个唯一标识符.
    + J/ u+ Q- L  W! @' ^表示查询中操作表的顺序,有三种情况:$ s& r* d: V/ m  C
    id相同:执行顺序由上到下: m( ~; |8 v5 o0 s' F' R7 J4 R
    id不同:如果是子查询,id号会自增,id越大,优先级越高。
    + r$ \9 u* R, @* p, hid相同的不同的同时存在
    $ k2 }) N. b5 Aid列为null的就表示这是一个结果集,不需要使用它来进行查询。! E0 n; o9 ]+ U: E2 h
    . [* l, x$ n/ M" }7 |( D/ c( Q
    二、select_type
    3 C- T0 \# }0 ^! J3 M( W3 a0 p- V" Q2 e0 Y3 \( I
    查询类型,主要用于区别普通查询、联合查询(union、union all)、子查询等复杂查询# N) v# V4 n3 [- y; F* i6 j! q+ K

    ; O( D$ E' {6 b( W' p4 f$ j- c6 {2.1、simple9 Z. r0 P, M* E% C
    表示不需要union操作或者不包含子查询的简单select查询。有连接查询时,外层的查询为simple  X+ v% H: K! U# y% I1 s

    * U5 k. o' x; o! \. g+ ?' BEXPLAIN select * from user) b) J. T7 W. L" k! Y' i

    5 Z+ h" w: I! B) {1 h- Q0 T" A 7.png
    2 ?2 T& [$ ~7 f& @# L8 J: n. q. z: p7 K" a: _
    EXPLAIN select u.id,u.addr_id,a.* from user u inner join taddr a on u.addr_id=a.id# d6 B2 S% T0 Z4 M% a6 Y) y1 O; [
    9.png
    1 g% I) r5 W1 Y# ?; G1 Z& S
    . B6 W% R) q2 ?* w& I2.2 primary- X- v) R; M2 y) j0 M
    一个需要union操作或者含有子查询的select,位于最外层的单位查询的select_type为primary。
    . w& r) ^; D$ l1 x0 u6 n  d* @* |5 m5 t( t
    explain select * from taddr t inner join (
    & A5 @1 L/ R. hselect addr_id from user ) u on t.id=u.addr_id, k' m: I# q. e" p5 X( f; K: P
    10.png
    4 t/ r  [8 M! a: M" f( K. n) |explain select * from user u where u.addr_id =1q! b' a' l7 d) [7 t! h2 E* P" u
    union all1 S; L( y, ]4 c' _; }5 n, r2 f+ {
    select * from user u where u.addr_id =2
    ' b( z6 a' ?6 B% o  N/ w 11.png 1 T9 X, T5 G: A3 c% Y) w

    2 \: h* t. V4 y7 L, p) l2.3 subquery0 S: P0 @4 p& u1 Z1 F- n+ k6 S( q
    除了from字句中包含的一查询外,其他地方出现的子查询都可能是subquery1 m8 i+ y& i7 I$ U( \
    ' Z6 C" l: s- R
    2.4 dependent subquery0 I/ I& o8 E9 {$ A
    : Q' t% \5 C, ?4 {$ I
    与dependent union类似,表示这个subquery的查询要受到外部表查询的影响
    / a. Z( _: X/ t9 \8 w$ H6 h  \$ Z7 a
    explain select u.name,(select t.province from taddr t where u.addr_id=t.id) from user u
    6 v/ D- h# v6 s' R+ \% V7 | 12.png
    / d' f3 g1 o& A8 A. G8 `" u% ^2.5 union
    7 S) ?8 E. m2 yunion连接的两个select查询,第⼀个查询是PRIMARY,除了第一个表外,第二个以后的表select_type都是union, V& G  g& F) z  r* I  _- Y: V

    2 r3 u" Z. k& @& X; c# ?三、table; }. J3 o, A4 V+ H8 b
    显示的查询表名,如果查询使用了别名,那么这里显示的是别名
    % `4 v; J0 w' |* W9 A2 W8 o' A8 G0 X如果不涉及对数据表的操作,那么这显示为null8 v9 F) E5 {7 ?/ s
    如果显示为尖括号括起来的就表示这个是临时表,后边的N就是执行计划中的id,表示结果来自于这个查询产生。
    * `# B/ o- p- V1 e: J$ q如果是尖括号括起来的<union M,N>,与类似,也是一个临时表,表示这个结果来自于union查询的id为M,N的结果集。* y. o0 ]5 e, t1 ^+ L5 M( p9 u
    1 u/ h5 V! \3 x" D/ c
    四、type2 {. K0 d/ P. q

    % z8 ?& n7 t0 O9 p4 l依次从好到差:2 V# F0 G  j9 ~' j3 R
    system,const,eq_ref,ref,fulltext,ref_or_null,unique_subquery,( u# ?8 C; E3 ?9 D
    index_subquery,range,index_merge,index,ALL
    # D9 I& }4 ?3 X2 V+ K* z$ ?* X6 n" s& d7 M
    除了all之外,其他的type都可以使⽤到索引,除了index_merge之外,其他的type只可以用到一个索引0 V3 [  F/ \) Y3 }! I) I
    5 u; g8 C$ x' F' z8 ]+ u. E. l
    4、1 system
    . O" Z( X7 D3 C. i* j/ }( K/ A4 g表中只有一行数据或者是空表。: c3 |8 m4 _' _, Y1 N
    3 T; b4 x' x1 l4 |
    4、2const( ]) Z/ [" }( ~% \. u7 }
    使用唯一索引或者主键,返回记录一定是1行记录的等值where条件时,通常type是const。其他数据库也叫做唯一索引扫描。
    . ?) x: K6 g% ^7 i. P* l6 J, u: A+ V$ `. x" E" R$ e
    4、3 eq_ref# a" h" ]. A9 R; i
    关键字:连接字段主键或者唯一性索引。& ~! B, _6 c" A; }6 f3 s: V
    此类型通常出现在多表的 join 查询, 表示对于前表的每一个结果, 都只能匹配到后表的一行结果. 并且查询的比较较操作通常是 ‘=’, 查询效率较高.
    ' x6 \7 R9 k0 L1 L2 V
    4 r. u$ D3 n) _2 q  s) A- a3 r3 B8 uEXPLAIN select u.id,u.addr_id,a.* from user u inner join taddr a on u.addr_id=a.id  c9 \% o- U. o- q9 s
    & ^3 Q  s2 X2 M. ]1 ?* Y7 M
    0 d; p) |* [. ]
    13.png ' b7 F" U4 f; C: Z
    7 o. C: k) J  g5 \* Z
    9 ?" U2 F5 }' A. q

    4、4 ref9 V3 F: z# b( t: v! Q
    针对非唯一性索引,使用等值(=)查询非主键。或者是使用了最左前缀规则索引的查询。

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

    14.png " w/ d+ [) f" \0 I( x! x

      @4 e$ w  l$ z4 F. ~$ q/ ^( b4.5 fulltext$ p! L, P  P8 u% ~- _. l1 z. I7 Y' G
    全文索引检索,要注意,全文索引的优先级很高,若全高索引和普通索引同时存在时,mysql不管代价,优先选择使用全文索引
    / N( r( G: b: D8 ^3 W$ V! C* `7 ~
    4、6 unique_subquery
    # e' ?) M7 ~" u7 I, G' g! b用于where中的in形式子查询,子查询返回不重复值唯一值* Y" k' a  q9 o
    % a' c& E; p, d# Q) ?3 x4 |
    4、7 index_subquery( [& M- T4 S- u) O
    用于in形式子查询使用到了辅助索引或者in常数列表,子查询可能返回重复值,可以使用索引将子查询去重。# [. z5 a  L, _# ^7 Q: h+ F

    1 R: |: X7 N+ k$ ?+ ~& }. Y4、8 range
    ! d* \' Q7 w/ ^+ }# ?( O0 U+ N索引范围扫描,常用于使用>,<,is null,between ,in ,like等运算符的查询中。
    0 `5 h. ^/ m; v7 _
    9 C0 H( t' A( l. G  N0 Mexplain select * from type_time a inner join (: z  M* i4 b0 O% Y
    select id from type_time where name =‘2’ and time in (‘2’,‘3’,‘4’) ) b on a.id=b.id% x; |" [) g+ q/ w5 J& Y" \: R

    & ?5 V8 }. i/ x  G) z/ W! J+ B- u/ s; k" Q
    15.png 1 L- r0 O; H/ I" s  G3 i+ |
    - L: m  }9 r8 _
    4、9 index
    8 B. z! s. B3 L, q5 z- b键字:条件是出现在索引树中的节点的。可能没有完全匹配索引。
    1 C. O: s3 n! B9 f" y& C+ g6 K索引全表扫描,把索引从头到尾扫一遍,常用于使用索引列就可以处理不需要读取数据文件的查询、可以使使用索引排序或者分组的查询。( h+ [/ l4 Y- v: T
    + _7 T+ p1 E- R0 ~& e; N. ~
    explain select * from user group by addr_id
    ! {8 ?8 `* C% p6 k! w1 l0 e" c( E/ h
    3 R  c7 K! j% H7 {' F9 f- q

    , {/ I( E4 |- _% T& Z0 x; m 16.png 0 @6 k* I' W  k2 \8 b3 W9 A
    - t$ E$ U. E* k; x* T# o6 E4 S
    explain select addr_id from user
      ^4 I, s, j* E0 v5 Z+ H- p
    * p( {; S8 Q) ~+ s/ m5 ?: S 17.png
    6 b/ p4 c: O* H+ n8 [
    % j' x2 U7 f+ X3 p3 F
    , J; ^, @# G! W7 v9 ~4、10 all, S, V% b  o0 o4 C1 W6 U- V5 d6 A
    这个就是全表扫描数据文件,然后再在server层进行过滤返回符合要求的记录。
    - G- X( c( s9 i7 i# q0 N8 N  e3 U/ R8 j! S2 L! R  m! t! y, N
    五、possible_keys- d) z6 k' _( P

    9 k* K6 i: n* N" `2 H此次查询中可能选用的索引,一个或多个
    0 ^1 l8 f+ f: ^4 A7 W; M* I
    ( k1 q# F) q8 g9 e& [六、key
    6 o. @6 k  o8 V' P/ J# u查询真正使使用到的索引,select_type为index_merge时,这里可能出现两个以上的索引,其他的select_type这里只会出现一个。
    7 E4 A3 p, D$ t9 Q$ o* l$ z5 `3 V& X. A0 J
    七、key_len* l2 R( F$ u) _- }0 ?

    ( [) n; s; R* t( ]用于处理查询的索引长度度,如果是单列索引,那就整个索引长度算进去,如果是多列索引,那么查& C  R& r* N7 k! H0 U
    询不一定都能使用到所有的列,具体使用到了多少个列的索引,这里就会计算进去,没有使用到的,这里不会计算进去。留意下这个列的值,算下你的多列索引总长度就知道有没有使用到所有的列了。
    , Q% H* d! @( n4 q0 R0 N$ B另外,key_len只计算where条件用到的索引长度,而排序和分组就算使用到了索引,也不会计算到key_len中。
    ! j% R" c# f, }# \6 g( S) {5 _0 X- Pexplain select id from type_time where name =‘2’ 用到长度303% q4 ?8 K( s9 O/ r( m

    " K; L# t9 n- H/ A 18.png 8 Q  v. L+ M" x- N7 D/ E5 U) T
    explain select id from type_time where name =‘2’ and time in (‘2’,‘3’,‘4’) 用到长度 1071
    1 q, S) e9 y, B8 X
    3 o$ ]7 d- B% @1 I& `5 B 19.png 6 s$ Y6 @1 K8 }6 i8 D
    1 z9 ^7 S/ _1 y$ ^2 ]
    八、ref# ?" c3 B5 E: ?$ f  @9 v: J7 ^; ~
    如果是使用的常数等值查询,这里会显示const' a3 u" X1 I" ?# M
    如果是连接查询,被驱动表的执行计划这里会显示驱动表的关联字段
    ; y1 Z0 ]% K; S如果是条件使用了表达式或者函数,或者条件列发生了内部隐式转换,这里可能显示为func: `3 n% ^# x1 X5 F

    9 t% b. f! Z3 r+ U& S九、rows
    % o6 K6 S$ U8 b% @这里是执行计划中估算的扫描行数,不是精确值(InnoDB不是精确的值,MyISAM是精确的值,主要原因是InnoDB使用了MVCC并发机制)8 n! g) M, W* s; v
    : `4 Y+ Q' K; `6 X8 g$ H8 P- P
    十、extra$ u9 T8 ?% o5 }, j# _. V/ i
    这个列包含不适合在其他列中显示但十分重要的额外的信息,其中比较常见有一些:
    ! p2 H; N$ E9 U4 k. u$ _" r* C1 E# G) I2 }! i: G
    10、1 using temporary) }# A5 |' e  h% ~
    表示使用了临时表存储中间结果。
    ) ^* u, r$ [1 Z1 o* Y. ^MySQL在对查询结果order by和group by时使用临时表
    : F: i& M6 `  h临时表可以是内存临时表和磁盘临时表,执行计划中看不出来,需要查看status变量,0 o- d6 ~& B% B! e
    used_tmp_table,used_tmp_disk_table才能看出来。5 ]( F8 w+ o1 Q! p. G
    + O  _+ K( t* @2 j1 x9 S: H
    explain select * from user u inner join taddr t on u.addr_id=t.id GROUP BY t.id
    ' u+ Y4 S  ~8 d
    3 f" W- ~0 C9 R8 d 20.png 1 V5 h: f1 A. l, x5 K7 V4 H
    % h6 }% k1 A. g( G' i* i
    10、2 using filesort0 ^  d9 J  X0 J& `4 ]
    排序时无法使用到索引时,就会出现这个。常用于order by和group by语句中+ U3 E7 W/ j& l' l9 P
    & s' l. C# k  |# b# r" M
    说明MySQL会使用个外部的索引排序,而不是按照索引顺序进行读取。
    0 M( N0 m0 v7 }/ lMySQL中无法利索引索引完成的排序操作称为“文件排序“# W2 A6 F/ T! C$ @1 V: D/ t

    4 T6 \1 S/ \* Z* ^5 V5 k6 M$ N& c+ F10、3 using index" q0 k9 m0 P" O8 @5 u+ q
    查询时不需要回表查询,直接通过索引就可以获取查询的数据。6 e7 F, i5 H9 Y  E3 Y$ t# ^
    表示相应的SELECT查询中使用到了覆盖索引(Covering Index),避免回表访问数据行,效率不
    $ ^& s3 `* f% v4 b4 u错。2 C  q  @8 ~7 c1 N# Z2 ]$ a
    如果同时出现Using Where ,说明索引被用来执行查找索引键值. ^1 l& p& Q# G! t
    如果没有同时出现Using Where ,表明索引用来读取数据来执行查找动作。8 v, `0 |& ?' a9 [* c

    3 t) y/ b7 ?3 \* C  K# W; a这里对索引的原理和explain做了一些介绍,需要索引需要建立之后对其改变查询方式可能会更能深刻理解 InnoDB 使用覆盖索引和非覆盖索引造成区别。这也是建立索引和使用sql需要特别考虑的问题。, O" n) g. R" m) l- H( r/ I2 ~
    ————————————————
    ) J! p" g8 f( z0 a5 t/ ]版权声明:本文为CSDN博主「筏镜」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。' s) j* V9 D$ n* `* C) L: y$ u& M
    原文链接:https://blog.csdn.net/fajing_feiyue/article/details/105616629
    : Q! T3 u5 _! G. K
    7 n' K! _* p2 o. o. `0 F
    + J+ G4 p; c5 ^6 h+ c

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

    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, 2025-8-28 02:41 , Processed in 1.050500 second(s), 53 queries .

    回顶部