MySQLインデックスを追加する3つの原則を簡単に理解する

MySQLインデックスを追加する3つの原則を簡単に理解する

1. インデックスの重要性

インデックスは、列に特定の値を持つ行をすばやく見つけるために使用されます。インデックスがない場合、MySQL はレコード 1 から開始し、関連する行が見つかるまでテーブル全体を読み取る必要があります。テーブルが大きいほど時間がかかります。クエリ対象のテーブル列にインデックスがある場合、MySQL はすべてのデータを調べなくても、データ ファイルの途中の検索位置にすばやく到達できます。行の大部分にアクセスする必要がある場合は、ディスクシークを回避するため、順次読み取りの方がはるかに高速になることに注意してください。

新華辞典で目次を使わずに漢字「张」を調べる場合、新華辞典の最初のページから最後のページまで検索する必要があり、2 時間かかる場合があります。辞書が厚ければ厚いほど、かかる時間も長くなります。ここで、ディレクトリを使用して、漢字「张」を検索します。张の最初の文字は z です。z で始まる漢字は 900 ページ以上あります。このヒントを使用すると、漢字を見つけるのに 1 分しかかからないかもしれません。これは、インデックス作成の重要性を示しています。しかし、インデックスを多く作成すればするほど良いというわけではありません。もちろんそうではありません。本のディレクトリが複数のレベルに分かれていると、目が回りそうになります。

2. 準備

//2つのテストテーブルを準備するmysql> CREATE TABLE `test_t` ( 
-> `id` int(11) NOT NULL auto_increment, 
-> `num` int(11) NOT NULL デフォルト '0', 
-> `d_num` varchar(30) NOT NULL デフォルト '0', 
-> 主キー (`id`) 
-> ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; 
クエリは正常、影響を受けた行は 0 行 (0.05 秒) 
mysql> テーブル `test_test` を作成します ( 
-> `id` int(11) NOT NULL auto_increment, 
-> `num` int(11) NOT NULL デフォルト '0', 
-> 主キー (`id`) 
-> ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; 
クエリは正常、影響を受けた行は 0 行 (0.05 秒) 
// データ挿入を容易にするストアド プロシージャを作成します。mysql> delimiter | 
mysql> プロシージャ i_test(pa int(11),tab varchar(30)) を作成します。 
-> 開始 
-> max_num int(11) をデフォルト 100000 として宣言します。 
-> i int をデフォルト 0 として宣言します。 
-> rand_num int を宣言します。 
-> double_num char を宣言します。 
-> 
-> タブ!= 'test_test'の場合 
-> test_t から count(id) を max_num に選択します。 
-> 私は < pa do 
-> max_num < 100000の場合 
-> cast(rand()*100 as unsigned) を rand_num に選択します。 
-> concat(rand_num,rand_num) を double_num に選択します。 
-> test_t(num,d_num)values(rand_num,double_num) に挿入します。 
-> 終了の場合; 
-> i = i +1 を設定します。 
-> 終了しながら; 
-> それ以外の場合 
-> test_test から count(id) を max_num に選択します。 
-> 私は < pa do 
-> max_num < 100000の場合 
-> cast(rand()*100 as unsigned) を rand_num に選択します。 
-> test_test(num)values(rand_num) に挿入します。 
-> 終了の場合; 
-> i = i +1 を設定します。 
-> 終了しながら; 
-> 終了の場合; 
-> 終了| 
クエリは正常、影響を受けた行は 0 行 (0.00 秒) 
mysql> 区切り文字; 
mysql> show variables like "%pro%"; // プロファイリングが有効になっているかどうかを確認します。デフォルトでは無効になっています。 +---------------------------+-------+ 
| 変数名 | 値 | 
+---------------------------+-------+ 
| プロファイリング | オフ | 
| プロファイリング履歴のサイズ | 15 | 
| プロトコルバージョン | 10 | 
| スレーブ圧縮プロトコル | オフ | 
+---------------------------+-------+ 
セット内の 4 行 (0.00 秒) 
mysql> set profiling=1; // オンにした後、インデックスを追加した後の実行時間を比較します。クエリは正常、0 行が影響を受けました (0.00 秒)

3. 例

1. 1つのテーブルにデータが少ないため、インデックスが速度に影響します。

mysql> call i_test(10,'test_t'); // test_t テーブルに 10 個の条件を挿入します。クエリは正常に完了しました。1 行が影響を受けました (0.02 秒) 
mysql> test_t から num を選択します (num!=0 の場合)。 
mysql> test_t から num を選択して、num!=0\G の場合、explain を実行します。 
************************** 1. 行 **************************** 
id: 1 
選択タイプ: シンプル 
テーブル: test_t 
タイプ: すべて 
可能なキー: NULL 
キー: NULL 
キー長さ: NULL 
参照: NULL 
行数: 10 
追加: where の使用 
セット内の 1 行 (0.00 秒) 
エラー: 
クエリが指定されていません 
mysql> test_t (num) にインデックス num_2 を作成します。 
クエリは正常、10 行が影響を受けました (0.19 秒) 
記録: 10 重複: 0 警告: 0 
mysql> test_t から num を選択します (num!=0 の場合)。 
mysql> test_t から num を選択して、num!=0\G の場合、explain を実行します。 
************************** 1. 行 **************************** 
id: 1 
選択タイプ: シンプル 
テーブル: test_t 
タイプ: インデックス 
可能なキー: num_2 
キー: num_2 
キーの長さ: 4 
参照: NULL 
行数: 10 
追加: where の使用; index の使用 
セット内の 1 行 (0.00 秒) 
エラー: 
クエリが指定されていません 
mysql> プロファイルを表示します。 
+----------+-------------+-------------------------------------------+ 
| Query_ID | 期間 | クエリ | 
+----------+-------------+-------------------------------------------+ 
| 1 | 0.00286325 | call i_test(10,'test_t') | // 10 個のレコードを挿入 | 2 | 0.00026350 | select num from test_t where num!=0 | 
| 3 | 0.00022250 | select num from test_t where num!=0 の説明 | 
| 4 | 0.18385400 | create index num_2 on test_t (num) | //インデックスを作成| 5 | 0.00127525 | select num from test_t where num!=0 | //インデックスを使用した後は、インデックスを使用しない場合の約 0.2 倍になります| 6 | 0.00024375 | explain select num from test_t where num!=0 | 
+----------+-------------+-------------------------------------------+ 
セット内の 6 行 (0.00 秒)

説明する:

  • id: SQLが実行される順序を示します
  • select_type: SIMPLE、PRIMARY、UNION、DEPENDENT UNION、UNION RESULT、SUBQUERY、DEPENDENT SUBQUERY、DERIVED クエリステートメントによってselect_typeが異なります。
  • テーブル:検索するテーブルの名前を示します
  • type : 使用するインデックスのタイプ、またはインデックスを使用するかどうかを示します。効率は、const、eq_reg、ref、range、index、ALL と、高から低までの範囲です。実際、これは SQL の記述方法に直接関係しています。たとえば、主キーを使用できる場合は、主キーを使用します。where の後の条件にインデックスを追加します。一意の場合は、一意のインデックスを追加します。
  • possible_keys : 可能なインデックス
  • キー: インデックスを使用する
  • key_len : 使用するインデックスの長さ
  • ref:テーブルから行を選択するためにキーと一緒に使用される列または定数。これは通常、複数のテーブルの結合クエリを実行するときに必要です。
  • 行数: 見つかった行数
  • 追加:追加の指示

以前、MySQL の distinct と group by のどちらが優れているかについてブログ記事を書きました。友人から、テスト結果が当時の私のテスト結果と異なるというメッセージが残されていました。その時は、例え話で説明しました。今日は、インデックスの動作原理を例の形でより直感的に表現する時間があります。

2. where の後に order by、group by などの条件を指定してフィルタリングする場合は、次のフィールドにインデックスを追加するのが最適です。 PRIMARY KEY、UNIQUE、INDEX などのインデックスは実際の状況に応じて選択しますが、多ければ多いほど良いです。適度にしてください。

3. 結合クエリやサブクエリなどの複数テーブル操作を実行する場合、関連するフィールドにインデックスを付ける必要があります。

mysql> call i_test(10,'test_test'); // test_test テーブルに 10 件のレコードを挿入します。クエリは成功しました。1 行が影響を受けました (0.02 秒) 
mysql> explain select a.num as num1,b.num as num2 from test_t as a left join tes 
a.num=b.num\G に対して b として t_test を実行します。 
************************** 1. 行 **************************** 
id: 1 
選択タイプ: シンプル 
テーブル: 
タイプ: インデックス 
可能なキー: NULL 
キー: num_2 
キーの長さ: 4 
参照: NULL 
行数: 10 
追加: インデックスの使用 
************************** 2. 行 **************************** 
id: 1 
選択タイプ: シンプル 
表: b 
タイプ: ref 
可能なキー: num_1 
キー: num_1 
キーの長さ: 4 
ref: bak_test.a.num //bak_test はデータベース名、a.num は test_t 行のフィールド: 1080 
追加: インデックスの使用 
セットに2行(0.01秒) 
エラー: 
クエリが指定されていません

データの量が特に多い場合は、インデックスを作成しても、共同クエリを使用しないことをお勧めします。

上記は議論を刺激することを目的とした、個人的な短い要約です。

以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • MySQLジョイントインデックスの左端一致原則の詳細な分析
  • MySQL の結合インデックスと左端一致原則の詳細な説明
  • MySQLのインデックス設計の原則と一般的なインデックスの違いについて簡単に説明します。
  • MySQL インデックスの左端原則のサンプルコード
  • 1 つの記事で MySQL インデックス作成の原則を理解する

<<:  APP (IOS、Android) を呼び出すモバイル H5 の記述例

>>:  vsftpdで仮想ユーザーログインを設定する方法

推薦する

vue+elementui+vuex+sessionStorage を使用して履歴タグ メニューを実装するためのサンプル コード

一般的には、左側にメニューがあった後、ページの上部に履歴タブ メニューを追加する必要があります。他の...

Vue で親子コンポーネントの値を双方向バインドするために v-model を使用するときに発生する問題と解決策

目次シナリオ解決してみる解決するシナリオ今日、コンポーネントの双方向データバインディングにv-mod...

MySQL カーディナリティ統計の簡単な分析

1. カーディナリティとは何ですか?カーディナリティとは、MySQL テーブルの列内の異なる値の数を...

mysql を解決: エラー 1045 (28000): ユーザー 'root'@'localhost' のアクセスが拒否されました (パスワードの使用: NO/YES)

1. 問題時々Mysqlにログインしてパスワードを入力すると、この状況が発生しますmysql -u...

HTML2 キャンバス SVG が認識されない場合の解決策

ウェブページを画像としてキャプチャする新機能があったので、人気のhtml2canvasを使ってみまし...

react-color を使用してフロントエンドのカラーピッカーを実装する方法

背景次の図に示すように、 react-color を使用してフロントエンド インターフェースのカラー...

MySQLの左結合を内部結合に素早く変換するプロセス

日々の最適化プロセス中に、奇妙なことに気付きました。同じ SQL にまったく異なる 2 つの実行プラ...

スクリプトを使用して、ワンクリックでDockerイメージをパッケージ化してアップロードします。

著者は1年以上マイクロフロントエンドプロジェクトに取り組んできました。チームは10個のマイクロアプリ...

HTMLのタグについての簡単な説明

0. タグとは何ですか? XML/HTML コードコンテンツをクリップボードにコピー<入力 t...

ミニプログラムは左スライドのドロワーメニューをネイティブに実装します

目次WXS レスポンス イベントプランAページ構造とスタイルWXS イベントコールバック関数WXS ...

CSS フレキシブルレイアウト FLEX、メディアクエリ、モバイルクリックイベントの実装

フレックスレイアウト定義: Flexレイアウトの要素は、 Flex 、または略して「コンテナー」と呼...

CSS を使用して親コンテナ div を img 画像で埋め、コンテナのサイズを調整する方法

ページに複数の画像を導入すると、画像のサイズがばらつくことがあります。しかし、それらを一貫したサイズ...

Linux で iostat コマンドを使用するチュートリアル

序文運用・保守を行う人がスキルを持っていなければ、サーバーを操作するのに恥ずかしさを感じてしまうと言...

クールな点滅アラームボタンをおすすめします

効果は以下のとおりです。 コードは次のとおりです (クリックすると展開してソース コードが表示されま...

Bash の山括弧の深い理解 (初心者向け)

序文Bash には、ls、cd、mv などの重要な組み込みコマンドが多数あるほか、grep、awk、...