基本的な実装を知っているあなたにテキストデータベース・グループの単一テーブルのクエリMySQLの取得を教えるためにアリR&Dシステム

MySQLユーザのこれらの私たちのために、通常、ほとんどの検索機能で使用します。スロークエリの最適化のいくつかをできるように随時オーバー失わDBAは、最適化は明らかではないが、まだも、ウールのクエリを実行する方法であれば、本当の技術を把握するための時間です。MySQLは、クエリの構文解析は、最適化するために、クエリオプティマイザに引き渡されるクエリオプティマイザモジュールの結果の後に呼ばれる機能があり、最適化は、いわゆる実行計画、インデックスを使用すべきか、実行計画のショーを生成することですクエリ、テーブル間の接続の順序は、鋸引きされ、最終的に実際にクエリを実行するための実行計画内のストレージエンジンステップによって提供される方法は呼び出し、クエリ結果がユーザに返されます。あなたが最初に歩くことを学ぶ前に、しかし、少し大きなこのテーマへのクエリオプティマイザは、実行することを学ぶ必要があり、単一テーブルのクエリを実行する方法を最初シュシュのMySQLには、この章(FROM句の後ろには〜だけで一つのテーブル、クエリの最も単純な種類です)。

物語を開発するために、テーブルを持って来ます。
基本的な実装を知っているあなたにテキストデータベース・グループの単一テーブルのクエリMySQLの取得を教えるためにアリR&Dシステム

私たちは、すなわち、SINGLE_TABLEテーブルのためにクラスタ化インデックスと4つのセカンダリインデックスを構築しました:

クラスタ化インデックスのID列が作成されました。

idx_key1セカンダリインデックスがkey1列に設立します。

Idx_key2セカンダリインデックスは、KEY2列を設立し、インデックスがユニークセカンダリインデックスされていることです。

idx_key3セカンダリインデックスは、KEY3の列に設立します。

idx_key_part二次インデックスは、関節指数でありkey_part1、key_part2、key_part3列について確立します。

その後、我々は、ランダムな値、私は書き込み、それ(列idは自動インクリメントの主キー列で挿入し、独自のプログラムを作成していない文の挿入特定のように挿入されている列を、残りのid列に加えて、テーブルのレコードのために10000行を挿入する必要があります我々は)手動で挿入する必要はありません。

アクセス方法(アクセス方法)のコンセプト

我々は鐘楼を検索する場合は確かにあなたがどこかへのルートを見つけるために、高い道徳的なマップを持っている、(ここでは高道徳的マップ広告平均としてされていない、彼らは私にお金を与えていない、あなたはまた、Baiduのマップああを使用することができます)私たちが選択するために私たちは本当にすべての権利ドライと豊かな十分なアイドルならば、大きな雁塔の間の経路に、そしてソフトウェアは、n個のルートのマップを与えられます、あなたはまた、正反対の方法で地球の周りの円の中に目的地に到達することができます。言い換えれば、どんなにどのようにして、私たちの究極の目標は、ビッグ雁塔にこの場所に到達することです。戻る過去にMySQLへ、私たちは通常、クエリの性質に書かれたものは唯一の宣言構文で、MySQLはちょうどMySQLは密かにそれからクエリ結果に従事しているかについてのルールが何であるかに沿ってデータを取得するために私たちに語りましたMySQLの自分の事。クエリの単一の表は、設計MySQLの実行の叔父は、大きく次の2つのカテゴリに分類クエリ。

全表スキャンのクエリを使用して

この実装はよく理解され、テーブルの各行が再びよく、検索条件が完成される結果セットに追加された一致するレコードを席巻している記録することです。これらのクエリは、このような方法で実行することができるかは関係ありませんが、もちろん、これは実装の最も愚かです。

インデックスクエリを使用します

直接使用する全表スキャンは、価格が高すぎる可能性がありますので、多数のレコードを横断するためにクエリを実行するので。検索条件でのクエリは、特定のインデックスに使用することができた場合は、その直接クエリを実行するためにインデックスを使用可能性が高いクエリの実行時間を加速することです。方法の問い合わせ多種多様を実行するために、インデックスを使用して、それは多くの種類に細分化することができます。

主キーまたはユニークセカンダリインデックスに対して同等のクエリ

通常のセカンダリインデックスに対して同等のクエリ

範囲のためにインデックス列を照会

直接はインデックス全体をスキャン

クエリを実行するためのデザインMySQLのMySQLの叔父の方法は、アクセス方法やアクセスタイプと呼ばれています。同じクエリは、実行するために異なるアクセスの様々な方法を使用することができる可能性が最終的な結果は同じですが、実行時間は、古い鼻離れが悪いかもしれないが大雁塔の鐘塔から、することができますロケットに乗るようにあなたは行く、あなたは、もちろん、行くためにカメを取ることができますして飛ぶことができます。以下は、慎重にさまざまなアクセス方法の特定のコンテンツチャネルへ。

CONST

時々、私たちはこのクエリを言って、主キー列でレコードを検索することができます:基本的な実装を知っているあなたにテキストデータベース・グループの単一テーブルのクエリMySQLの取得を教えるためにアリR&Dシステム

MySQLの主キーは、直接このようなユーザレコードクラスタ化インデックスを、対応する配置されます。基本的な実装を知っているあなたにテキストデータベース・グループの単一テーブルのクエリMySQLの取得を教えるためにアリR&Dシステム

原谅我把聚簇索引对应的复杂的 B+树结构搞了一个极度精简版,为了突出重点,我们忽略掉了 页的结构,直接把所有的叶子节点的记录都放在一起展示,而且记录中只展示我们关心的索引列,对于 single_table表的聚簇索引来说,展示的就是 id列。我们想突出的重点就是: B+树叶子节点中的记录是按照索引列排序的,对于的聚簇索引来说,它对应的 B+树叶子节点中的记录就是按照 id列排序的。 B+树本来就是一个矮矮的大胖子,所以这样根据主键值定位一条记录的速度贼快。类似的,我们根据唯一二级索引列来定位一条记录的速度也是贼快的,比如下边这个查询:
基本的な実装を知っているあなたにテキストデータベース・グループの単一テーブルのクエリMySQLの取得を教えるためにアリR&Dシステム

这个查询的执行过程的示意图就是这样:
基本的な実装を知っているあなたにテキストデータベース・グループの単一テーブルのクエリMySQLの取得を教えるためにアリR&Dシステム

可以看到这个查询的执行分两步,第一步先从 idx_key2对应的 B+树索引中根据 key2列与常数的等值比较条件定位到一条二级索引记录,然后再根据该记录的 id值到聚簇索引中获取到完整的用户记录。

设计 MySQL的大叔认为通过主键或者唯一二级索引列与常数的等值比较来定位一条记录是像坐火箭一样快的,所以他们把这种通过主键或者唯一二级索引列来定位一条记录的访问方法定义为: const,意思是常数级别的,代价是可以忽略不计的。不过这种 const访问方法只能在主键列或者唯一二级索引列和一个常数进行等值比较时才有效,如果主键或者唯一二级索引是由多个列构成的话,索引中的每一个列都需要与常数进行等值比较,这个 const访问方法才有效(这是因为只有该索引中全部列都采用等值比较才可以定位唯一的一条记录)。

对于唯一二级索引来说,查询该列为 NULL值的情况比较特殊,比如这样:基本的な実装を知っているあなたにテキストデータベース・グループの単一テーブルのクエリMySQLの取得を教えるためにアリR&Dシステム
因为唯一二级索引列并不限制 NULL值的数量,所以上述语句可能访问到多条记录,也就是说上边这个语句不可以使用 const访问方法来执行。

ref

有时候我们对某个普通的二级索引列与常数进行等值比较,比如这样:基本的な実装を知っているあなたにテキストデータベース・グループの単一テーブルのクエリMySQLの取得を教えるためにアリR&Dシステム

对于这个查询,我们当然可以选择全表扫描来逐一对比搜索条件是否满足要求,我们也可以先使用二级索引找到对应记录的 id值,然后再回表到聚簇索引中查找完整的用户记录。由于普通二级索引并不限制索引列值的唯一性,所以可能找到多条对应的记录,也就是说使用二级索引来执行查询的代价取决于等值匹配到的二级索引记录条数。如果匹配的记录较少,则回表的代价还是比较低的,所以 MySQL可能选择使用索引而不是全表扫描的方式来执行查询。设计 MySQL的大叔就把这种搜索条件为二级索引列与常数等值比较,采用二级索引来执行查询的访问方法称为: ref。我们看一下采用 ref访问方法执行查询的图示:基本的な実装を知っているあなたにテキストデータベース・グループの単一テーブルのクエリMySQLの取得を教えるためにアリR&Dシステム
从图示中可以看出,对于普通的二级索引来说,通过索引列进行等值比较后可能匹配到多条连续的记录,而不是像主键或者唯一二级索引那样最多只能匹配1条记录,所以这种 ref访问方法比 const差了那么一丢丢,但是在二级索引等值比较时匹配的记录数较少时的效率还是很高的(如果匹配的二级索引记录太多那么回表的成本就太大了),跟坐高铁差不多。不过需要注意下边两种情况:

1、二级索引列值为 NULL的情况,不论是普通的二级索引,还是唯一二级索引,它们的索引列对包含 NULL值的数量并不限制,所以我们采用 key IS NULL这种形式的搜索条件最多只能使用 ref的访问方法,而不是 const的访问方法。

2、对于某个包含多个索引列的二级索引来说,只要是最左边的连续索引列是与常数的等值比较就可能采用 ref的访问方法,比方说下边这几个查询:基本的な実装を知っているあなたにテキストデータベース・グループの単一テーブルのクエリMySQLの取得を教えるためにアリR&Dシステム

但是如果最左边的连续索引列并不全部是等值比较的话,它的访问方法就不能称为 ref了,比方说这样:基本的な実装を知っているあなたにテキストデータベース・グループの単一テーブルのクエリMySQLの取得を教えるためにアリR&Dシステム

refornull

有时候我们不仅想找出某个二级索引列的值等于某个常数的记录,还想把该列的值为 NULL的记录也找出来,就像下边这个查询:基本的な実装を知っているあなたにテキストデータベース・グループの単一テーブルのクエリMySQLの取得を教えるためにアリR&Dシステム

当使用二级索引而不是全表扫描的方式执行该查询时,这种类型的查询使用的访问方法就称为 ref_or_null,这个 ref_or_null访问方法的执行过程如下:
基本的な実装を知っているあなたにテキストデータベース・グループの単一テーブルのクエリMySQLの取得を教えるためにアリR&Dシステム

可以看到,上边的查询相当于先分别从 idx_key1索引对应的 B+树中找出 key1 IS NULL和 key1='abc'的两个连续的记录范围,然后根据这些二级索引记录中的 id值再回表查找完整的用户记录。

range

我们之前介绍的几种访问方法都是在对索引列与某一个常数进行等值比较的时候才可能使用到( ref_or_null比较奇特,还计算了值为 NULL的情况),但是有时候我们面对的搜索条件更复杂,比如下边这个查询:
基本的な実装を知っているあなたにテキストデータベース・グループの単一テーブルのクエリMySQLの取得を教えるためにアリR&Dシステム

我们当然还可以使用全表扫描的方式来执行这个查询,不过也可以使用 二级索引+回表的方式执行,如果采用 二级索引+回表的方式来执行的话,那么此时的搜索条件就不只是要求索引列与常数的等值匹配了,而是索引列需要匹配某个或某些范围的值,在本查询中 key2列的值只要匹配下列3个范围中的任何一个就算是匹配成功了:

key2的值是 1438

key2的值是 6328

key2的值在 38和 79之间。

设计 MySQL的大叔把这种利用索引进行范围匹配的访问方法称之为: range。

小贴士:

此处所说的使用索引进行范围匹配中的 索引 可以是聚簇索引,也可以是二级索引。

如果把这几个所谓的 key2列的值需要满足的 范围在数轴上体现出来的话,那应该是这个样子:
基本的な実装を知っているあなたにテキストデータベース・グループの単一テーブルのクエリMySQLの取得を教えるためにアリR&Dシステム

也就是从数学的角度看,每一个所谓的范围都是数轴上的一个 区间,3个范围也就对应着3个区间:

范围1: key2=1438

范围2: key2=6328

范围3: key2∈[38,39],注意这里是闭区间。

我们可以把那种索引列等值匹配的情况称之为 单点区间,上边所说的 范围1和 范围2都可以被称为单点区间,像 范围3这种的我们可以称为连续范围区间。

index

看下边这个查询:
基本的な実装を知っているあなたにテキストデータベース・グループの単一テーブルのクエリMySQLの取得を教えるためにアリR&Dシステム

key_part2以来ない共同インデックスidx_key_part左端の列インデックス、我々はrefまたは範囲へのアクセス方法を使用して、この文を実行することはできませんので。しかし、次の2つの条件を満たしているクエリ:

これは、リストに3つの列のみ照会:key_part1、key_part2、key_part3を、インデックスidx_key_partターンは3つの列が含まれています。

唯一の基準key_part2列を検索します。この列は、インデックスのidx_key_partに含まれています。

私たちは、直接比較することができていることkey_part2 =葉ノードトラバーサルこの条件の指標が満たされるidx_key_part、セカンダリインデックスレコードがkey_part1、key_part2の成功に一致するように記録することで、値がライン上で直接、結果セットにkey_part3列を追加した「ABC」 A。クラスタ化インデックスよりも小さい2つの記録されたインデックスは、ポリ記録(クラスタ化インデックスレコードすべてのユーザー定義列と、いわゆる隠された列を格納するために、インデックスレコードのみ2つの列を、主キーインデックスが格納されている)、この処理もないので直接トラバースセカンダリインデックスが直接トラバース多くのクラスタード・インデックスのコストよりも小さくなるように、テーブルバック動作、MySQLの叔父は、インデックスレコードの実装を横断するデザイン用途2と呼ばれる入れ:indexallを

すべて

最も直接的な方法は、それが直接、クラスタ化インデックスをスキャンされ、我々はすでにInnoDBテーブルのために数え切れないほど全表スキャンを、言及しているクエリの実行にあり、MySQLの叔父は、この設計の使用にクエリコールを実行するための全表スキャンを置きます:全て

もっとMySQLが動作しているかについて、あなたがコンテンツ「のハイパフォーマンスMySQLの電子版」で見ることができるのMySQLの中心的な概念のいくつかは、このようなサーバーのパフォーマンスのベンチマークとして、比較的単純な言語、進ん説明し、ビューの白色点から、非常に充実していますデータ型最適化クエリのパフォーマンスの最適化は、オリジナルイラストの作品の何百もの、など多くの知識の可用性、単語についての単語の数十万人の合計をコピーします。私は主に、学習曲線ので、少しスムーズに、MySQLは時間の短い期間ではこれらの一見より曖昧な知識を習得するために高度な平均プログラマの学習曲線を減らしたいです。

おすすめ

転載: blog.51cto.com/14528283/2452583