Mysqlはインデックスに頼れるけど、バイトに頼るしかない…。

coldplay.xixi
リリース: 2020-10-26 17:44:33
転載
2156 人が閲覧しました

#mysql 教程 リストの関連インデックス。

Mysqlはインデックスに頼れるけど、バイトに頼るしかない…。

.markdown-body{単語区切り:単語区切り;行の高さ:1.75;フォントの太さ:400;フォントサイズ:15px ;overflow-x:hidden;color:#333}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{line-高さ:1.5;マージントップ:35px;マージンボトム:10px;パディングボトム:5px}.markdown-body h1{font-size:30px;マージンボトム:5px}.markdown-body h2{パディングボトム: 12px;font-size:24px;border-bottom:1px ソリッド #ececec}.markdown-body h3{font-size:18px;padding-bottom:0}.markdown-body h4{font-size:16px}.markdown- body h5{font-size:15px}.markdown-body h6{margin-top:5px}.markdown-body p{line-height:inherit;margin-top:22px;margin-bottom:22px}.markdown-body img {max-width:100%}.markdown-body hr{border:none;border-top:1px Solid #ddd;margin-top:32px;margin-bottom:32px}.markdown-body code{word-break:break -word;border-radius:2px;overflow-x:auto;background-color:#fff5f5;color:#ff502c;font-size:.87em;padding:.065em .4em}.markdown-body code,.markdown- body pre{font-family:Menlo,Monaco,Consolas,Courier New,monospace}.markdown-body pre{overflow:auto;position:relative;line-height:1.75}.markdown-body pre>code{font-size: 12px;パディング:15px 12px;margin:0;word-break:normal;display:block;overflow-x:auto;background:#f8f8f8}.markdown-body a{text-decoration:none;color:#0269c8;border -bottom:1px Solid #d1e9ff}.markdown-body a:active,.markdown-body a:hover{color:#275b8c}.markdown-body table{display:inline-block! important;font-size:12px;width :auto;max-width:100%;overflow:auto;border:1px Solid #f6f6f6}.markdown-body thead{background:#f6f6f6;color:#000;text-align:left}.markdown-body tr:nth -child(2n){背景色:#fcfcfc}.markdown-body td,.markdown-body th{パディング:12px 7px;line-height:24px}.markdown-body td{min-width:120px}.markdown -body blockquote{color:#666;padding:1px 23px;margin:22px 0;border-left:4px Solid #cbcbcb;background-color:#f8f8f8}.markdown-body blockquote:after{display:block;content:" "}.markdown-body blockquote>p{margin:10px 0}.markdown-body ol,.markdown-body ul{padding-left:28px}.markdown-body ol li,.markdown-body ul li{margin-bottom :0;list-style:inherit}.markdown-body ol li .task-list-item,.markdown-body ul li .task-list-item{list-style:none}.markdown-body ol li .task- list-item ol,.markdown-body ol li .task-list-item ul,.markdown-body ul li .task-list-item ol,.markdown-body ul li .task-list-item ul{margin-top :0}.markdown-body ol ol,.markdown-body ol ul,.markdown-body ul ol,.markdown-body ul ul{margin-top:3px}.markdown-body ol li{padding-left:6px} @media (最大幅:720px){.markdown-body h1{font-size:24px}.markdown-body h2{font-size:20px}.markdown-body h3{font-size:18px}}

一、インデックスデータウェア構造

面试の時候肯定会问これ一问题、mysql は何ですか?インデックス呢? b'?hash などの他のインデックスは選択しないでください。

#ハッシュ インデックスの话
、ハッシュは应一值的であるため、范围蟥询をサポートしていません、没法范围蟥询

  • 二分木の場合、左のサブツリーがルートノードよりも小さく、右のサブツリーよりも小さいことが特徴です。ルート ノードの値に問題がある場合、リンク リストに縮退する可能性があります。つまり、ツリーは分岐せず、ツリーは常に左または右に移動するため、半分で検索することはできません。 IO の数を減らすために使用します。範囲クエリはサポートされていません。範囲クエリを使用する場合は、毎回ルートからたどる必要があります。また、ツリーが高すぎます。ツリーが高くなるほど、IO 操作の頻度が高くなり、無駄が生じます。 resource.

  • バイナリ ツリー のバランスをとった場合、バイナリ ツリーは存在しません。これには、リンク リストに退化するという欠点があります。 、その左右の子ノードの差は最大 1 レベルですが、範囲検索はサポートされていないため、バイナリ ツリーの問題と同じです。

  • B ツリー, バイナリ ツリーと比較すると、ツリーは非常に短く太く、IO 操作が削減されます。マルチフォーク ツリーです。各ノードには対応するデータ行が格納されます。ただし、この行のデータが増加すると、列が増加し続けるため、このページに格納されるノードの数は減少します。これは、占有スペースが増加し続け、ツリーがますます高くなり、IO 操作の数が増加するためです。同時に、範囲検索はサポートされていません。同じサイズのスペースに多くのノード データを保存できる方が良いため、次の b-tree

  • b-tree があります。 非リーフ ノードはデータの行全体ではなくインデックス データのみを格納しますが、リーフ ノードは冗長な冗長な非リーフ ノードであり、リーフ ノードは二重リンク リストにもリンクされているため、順次検索が容易になります。 b B ツリーと比較して、ツリーはより分厚く、ディスク IO 時間が少なくなります

  • 2. mysql のインデックス タイプ

    • クラスター化インデックスと非クラスター化インデックス
    ##単純にできます。として理解される クラスター化インデックスは主キー インデックスであり、非クラスター化インデックスは通常のインデックスです。

    本質的な違いは次のとおりです。

    クラスター化インデックスリーフ ノードにはデータの行全体が格納されます

    innodb は主キーを介してクラスター化インデックスを実装します。主キーがない場合は、実装する空でない一意のインデックスが選択されます。主キーがない場合は、暗黙的に生成されます。クラスター化インデックスを実装するための主キー

    ##非クラスター化インデックスには、インデックス値と主キー値が格納されます

    • ##通常のインデックス

      テーブルには複数の通常のインデックスが存在し、任意のフィールドにインデックスを確立できます。通常作成するインデックスのほとんどは通常のインデックスです

    • #結合インデックス
      複数のフィールドを組み合わせて作成されるインデックス

    • 一意のインデックス
      ビジネスで一意のインデックスを確立するのに適しているのはこのフィールドだけです。テーブルには複数の一意のインデックスが存在する可能性があります

    • ##主キー インデックス
    • と一意 インデックスと同じように、主キー インデックスも一意です。違いは、テーブルには主キー インデックスが 1 つしか持てないことです。

    ##3. インデックスについて sql

    主キー インデックスの作成
    ALTER TABLE test add  PRIMARY  KEY (id)复制代码
    ログイン後にコピー
    一意のインデックスの作成

    ALTER TABLE test add UNIQUE idx_id_card(id_card)复制代码
    ログイン後にコピー

    通常のインデックスを作成します

    ALTER TABLE test add INDEX idx_name(name)复制代码
    ログイン後にコピー
    ログイン後にコピー

    結合インデックスを作成します

    ALTER TABLE test add INDEX idx_age_name(age,name)复制代码
    ログイン後にコピー

    インデックス名を変更します: 最初に削除してから追加します

    インデックスを削除します (2 つの方法)

    ALTER TABLE test DROP INDEX idx_id_cardDROP INDEX idx_id_card on test --删除主键索引DROP PRIMARY key on test  ALTER TABLE test DROP  PRIMARY key复制代码
    ログイン後にコピー

    テーブル内のインデックスを表示

    SHOW INDEX FROM test复制代码
    ログイン後にコピー
    ログイン後にコピー

    分析インデックス

    EXPLAIN SELECT * from test WHERE name = "xhJaver"复制代码
    ログイン後にコピー
    ログイン後にコピー

    我们先给name字段添加一个索引,索引名字叫做idx_name

    ALTER TABLE test add INDEX idx_name(name)复制代码
    ログイン後にコピー
    ログイン後にコピー

    查看test表中的索引

    SHOW INDEX FROM test复制代码
    ログイン後にコピー
    ログイン後にコピー

    其中的属性

    • table: 表名

    • Non_unique: 能重复的话为1,不能重复的话为0,我们主键的那里是0,而name那里是1,因为name可以重复,而主键不能重复

    • Key_name: 索引名称

    • Seq_in_index:索引中列的顺序

    • Column_name:列名称

    • Collation:列以什么方式存储的,A升序,null无序

    • Cardinality:数目越大,则使用该索引的可能性越大

    • Sub_part:如果列只是部分的编入索引,则被编入索引的字符数目,如果整列被编入索引,则为null

    • Packed:关键字是否被压缩,null表示没有被压缩

    • Null:如果该列含有null,则为yes,如果没有null,则为no

    • Index_type:索引数据结构

    • Comment:多种评注

    四、回表查询

    select * from test where  name = "xhJaver"复制代码
    ログイン後にコピー

    假如说我们name字段建立了索引,然后当我们运行这一句sql语句的时候,因为建立的是普通索引,所以我们的b+树的叶子节点存储的数据是id,我们会找到name是xhJaver的这条记录的id,再根据这个id,去主键索引的那棵b+树去查询,查询到叶子节点时即查询出这条记录,可见这个过程中,我们从一棵树跑到了另一棵树继续查,这样就叫做“回表查询”,那有没有办法只查一棵树就可以查询出结果呢?

    五、覆盖索引

    办法当然是有的啦,那就是覆盖索引,我们注意到,刚才这个sql语句时查询出来了所有元素,假如说我们这样写的话

    select address from test where  name = "xhJaver"复制代码
    ログイン後にコピー

    假如说我们建立的索引是(name,address)那么这个时候(name,address)这棵b+树的叶子节点存储的数据就包括address了,此时就不需要再根据name = "xhJaver"的id去第二棵树查了,这样就避免了回表查询

    六、最左匹配原则

    假如说现在我们写一个这样的sql语句

    select *  from test where  name = "xhJaver" and age =23  and address="京东"复制代码
    ログイン後にコピー

    并且我们建立的索引是(name,address,age)这样是会用到(name,address,age)索引的,可是如果要这样写的话

    select *  from test where  name = "xhJaver" and age >23  and address="京东"复制代码
    ログイン後にコピー

    这样只会用到(name,age)这两个索引,从左边开始匹配,如果要是遇到范围查询的话,则不继续往右匹配索引

    七、explain分析索引语句

    我们用explain语句解析一下下面这条sql语句

    EXPLAIN SELECT * from test WHERE name = "xhJaver"复制代码
    ログイン後にコピー
    ログイン後にコピー

    它的属性有

    id: 执行的顺序

    • id相同时,顺序从上到下执行
    • id不同时,id大的先执行

    select_type: 查询的类型

    • primary: 最外层的查询被标记为primary
    • simple: 简单查询,没有关联其他表,就一张表
    • subquery: 在where或者select中的子查询
    • derived: 衍生虚拟表 例如from(子查询) t,这个子查询的结果就被放在虚拟表t中

    table: 关于哪张表的

    partitions: 分区相关(还没搞懂呜呜呜)

    type:访问类型

    性能由好至坏依次是 system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL一般来说,好的sql查询至少达到range级别,最好能达到ref

    • system: テーブルにはデータが 1 行だけあります。

    • const: 定数クエリは次のとおりです。通常、主キーと等しいものを比較するために使用されます。 インデックスを使用して 1 つのクエリで見つけられる定数です。

    • eq_ref: 一意のインデックス。各インデックスはデータの一部に対応します。主キーインデックスなど、

    • ref: 一意ではないインデックス。各インデックスは、通常のインデックス

      # など、複数のデータ行に対応する場合があります。
    • ##range : >、<、in、between、その他のクエリを使用した範囲クエリ

    • index:フル テーブル スキャン、ただしインデックス ツリー全体を走査します

    • all: フル テーブル スキャン、インデックスは使用されません

    possible_keys

    : クエリ フィールドにインデックスがある場合、それが表示されます。

    key

    : 使用される特定のインデックス。カバリング インデックスがused, possible_keys は null で、key

    key_len

    : インデックスで使用されるバイト数、実際の長さではなく、可能な最大長です。key_len は次の値に基づいて計算されます。テーブルから取得されるのではなく、テーブル定義に基づいて行われます

    ref

    : どのフィールドにインデックスが付けられているかを示します

    rows

    : 行数を大まかに推定します読む必要があります

    filtered

    : 条件によってフィルターされた行数の推定パーセンテージを示します。 #補足

    :

      ファイルソートの使用: mysql がインデックスを使用して完了できないソートは、ファイルソートと呼ばれます
    • 一時テーブルの使用: 中間結果を保存するために一時テーブルを使用します。MySQL はクエリ結果を並べ替えるときに一時テーブルを使用します。これは、order by および group by
    • で一般的です。
    • Using index:使用了覆盖索引,查询内容在索引内

      1. 如果出现了Using where,表示对查询出来的数据进行了过滤
      2. 如果没有出现Using where,表示对查询出来的数据没有进行过滤
    • 只有Using where 查询内容不在索引内,且对查出来的数据进行了过滤

    1. EXPLAIN SELECT (select student.id from student WHERE student.`name`="xhJaver") FROM teacher2. EXPLAIN SELECT * FROM teacher where teacher.id = (select student.id from student WHERE student.`name`="xhJaver") 
    复制代码
    ログイン後にコピー

    我们写几个sql语句实际分析下 1.SELECT后面2.where后面

    我们就拿后面这个图来实战分析一下,挑几个重要的属性说一下

    select_type:

    • 我们最外层的查询是 from teacher 所以table为teacher的那个表的select_type就是primary

    • select/where后面的括号中的查询语句中的表是student,所以table为student的那个表的select_type就是subquery

    table: 这条sql查询用到的表

    type: 访问类型

    • 第一行const : teacher.id =巴拉巴拉巴拉(这个是常数)主键和常数比较时,这个表最多有一个匹配数据,只读取一次

    • 第二行ref:代表用到了普通索引,就是这个索引name和xhJaver匹配,可能匹配到很多相同的值

    possible_key: 代表可能用到的索引,但是不一定会用到

    key: 代表用到的索引, 用到了idx_name,PRIMARY索引

    ref: 这一列显示了在key列记录的索引中,表查找值所用到的列或常量, 常见的有:const,字段名

    extra:

    • using index: 一般是使用了覆盖索引,看我们这个sql语句,
    select student.id from student WHERE student.`name`="xhJaver"复制代码
    ログイン後にコピー

    name字段有索引,查询的是id,b+树叶子节点存的数据就是id,所以不需要回表查询了,用到了覆盖索引

    八、索引失效原因

    1. 遇到范围查询(>,<,like,beetwon),右边的索引列会失效

    2. 索引字段不能有函数操作或者不能是表达式的一部分

    3. 索引字段隐式类型转换 索引字段类型是string,我们传进来个int

    4. 使用时or,is null ,is not null , !=, <>, like "%xxx" 索引会失效

    但是用覆盖索引就可以解决 like左模糊查询走不到索引的情况 如果只select索引字段,或者select索引字段和主键,也会走索引的。

    更多相关免费学习推荐:mysql教程(视频)

    以上がMysqlはインデックスに頼れるけど、バイトに頼るしかない…。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

    関連ラベル:
    ソース:juejin.im
    このウェブサイトの声明
    この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
    最新の問題
    人気のチュートリアル
    詳細>
    最新のダウンロード
    詳細>
    ウェブエフェクト
    公式サイト
    サイト素材
    フロントエンドテンプレート