MySQL インデックスをより効率的にするにはどうすればよいですか?
この記事では、MySQL でインデックスをより効率的に設計する方法についての知識を提供しました。次に、インデックスの設計方法を見てみましょう。インデックスを使用することによってのみ、下位インターフェイスの RT を改善し、ユーザーの健全性を向上させることができます. 皆様のお役に立てれば幸いです。
インデックスはリンク リストに基づいたツリー状のツリー構造であり、データを迅速に取得できることがわかっています。現在、ほとんどすべての RDBMS データベースにはインデックス機能が実装されています。 MySQL、B Tree インデックス、MongoDB の BTree インデックスなど。
業務開発の過程において、インデックス設計が効率的であるか否かは、インターフェースに対応するSQLの実行効率を左右し、インデックスが効率的であればインターフェースの応答時間も短縮され、コストも削減できます。私たちの現実的な目標は次のとおりです。インデックス設計 -> インターフェースの応答時間の削減 -> サーバー構成の削減 -> コストの削減。これは最終的にはコストで実装する必要があります。上司がコストを最も懸念しているためです。
今日は、MySQL のインデックスとインデックスの設計方法についてお話します。インデックスを使用することによってのみ、下位インターフェイスの RT を改善し、ユーザーの健康を改善することができます。
MySQL のインデックス
MySQL の InnoDB エンジンは、B ツリー構造を使用してインデックスを保存し、データ クエリ中のディスク IO の数を最小限に抑えることができます。ツリーはクエリのパフォーマンスに直接影響し、通常、ツリーの高さは 3 ~ 4 層に維持されます。
B ツリーはルート、ブランチ、リーフの 3 つの部分で構成されます。ルートとブランチにはデータは格納されず、ポインタ アドレスのみが格納されます。すべてのデータはリーフ ノードに格納され、ノード間では双方向リンク リストが使用されます。リーフ ノード。リンク、構造は次のとおりです:
上記からわかるように、各リーフ ノードは 3 つの部分、つまり先行ポインタ p_prev、data で構成されます。 dataと後続ポインタp_next、while data データは順番に並んでいます。デフォルトは昇順のASCです。Bツリーの右側に分布するキー値は常に左側よりも大きくなります。同時に、データからの距離も離されます。各リーフへのルートは等しい、つまり、どのリーフ ノードへのアクセスに必要な IO も同じ、つまり、インデックス ツリーの高さはレベル 1 IO 操作です。
MySQL のインデックスは、ディスク領域を占有する小さなテーブルと考えることができます。インデックスを作成するプロセスは、実際には、インデックス列に従ってソートするプロセスです。まず、sort_buffer_size でソートします。ソートするデータが大きい場合、sort_buffer_size の容量に達しない場合は、一時ファイルを使用してソートする必要がありますが、最も重要なことは、ソート操作 (distinct、group by、order by) がインデックス作成によって回避できることです。
クラスタードインデックス
MySQLのテーブルはIOT(Index Organization Table、インデックス組織テーブル)であり、データは主キーID順(論理的に連続、物理的に不連続)に格納されます。主キー ID は、データの行全体を格納するクラスター化インデックスです。明示的に主キーが指定されていない場合、MySQL はすべてのカラムを結合して主キーとして row_id を構築します (テーブル ユーザー (id、user_id、 user_name、phone、主キー(id))、id はクラスター化インデックスであり、データ id、user_id、user_name、phone の行全体が格納されます。
補助インデックス
補助インデックスはセカンダリ インデックスとも呼ばれ、インデックス列の保存に加えて、主キー ID も保存されます。 user_name のインデックス idx_user_name(user_name) に関しては、実際には idx_user_name(user_name, id) と同等です。MySQL は補助インデックスの最後に主キー ID を自動的に追加します。Oracle データベースに精通している人なら誰でもそれを知っています。インデックス列、インデックスには row_id も格納されます (データを表す物理的な場所は、オブジェクト番号、データ ファイル番号、データ ブロック番号、データ行番号の 4 つの部分で構成されます)。また、補助インデックスを作成するときに主キー ID を表示することもできます。
-- 创建user_name列上的索引mysql> create index idx_user_name on users(user_name);-- 显示添加主键id创建索引mysql> create index idx_user_name_id on users(user_name,id);-- 对比两个索引的统计数据mysql> select a.space as tbl_spaceid, a.table_id, a.name as table_name, row_format, space_type, b.index_id , b.name as index_name, n_fields, page_no, b.type as index_type from information_schema.INNODB_TABLES a left join information_schema.INNODB_INDEXES b on a.table_id =b.table_id where a.name = 'test/users';+-------------+----------+------------+------------+------------+----------+------------------+----------+------| tbl_spaceid | table_id | table_name | row_format | space_type | index_id | index_name | n_fields | page_no | index_type |+-------------+----------+------------+------------+------------+----------+------------------+----------+------| 518 | 1586 | test/users | Dynamic | Single | 1254 | PRIMARY | 9 | 4 | 3 || 518 | 1586 | test/users | Dynamic | Single | 4003 | idx_user_name | 2 | 5 | 0 || 518 | 1586 | test/users | Dynamic | Single | 4004 | idx_user_name_id | 2 | 45 | 0 |mysql> select index_name, last_update, stat_name, stat_value, stat_description from mysql.innodb_index_stats where index_name in ('idx_user_name','idx_user_name_id');+------------------+---------------------+--------------+------------+-----------------------------------+| index_name | last_update | stat_name | stat_value | stat_description |+------------------+---------------------+--------------+------------+-----------------------------------+ | idx_user_name | 2021-01-02 17:14:48 | n_leaf_pages | 1358 | Number of leaf pages in the index || idx_user_name | 2021-01-02 17:14:48 | size | 1572 | Number of pages in the index || idx_user_name_id | 2021-01-02 17:14:48 | n_leaf_pages | 1358 | Number of leaf pages in the index || idx_user_name_id | 2021-01-02 17:14:48 | size | 1572 | Number of pages in the index |
2 つのインデックスの結果を比較します。n_fields はインデックス内の列数を表し、n_leaf_pages はインデックス内のリーフ ページ数を表し、size はインデックス内の合計ページ数を表します。データ比較を通じてこれを確認してください。補助インデックスには主キー ID が含まれており、これは 2 つのインデックスが完全に一貫していることも示しています。
n_fields | n_leaf_pages | size | |||
---|---|---|---|---|---|
#2 | 1358 | 1572 | |||
2 | 1358 | 1572 |
复合索引 | Type | Rows | 参与过滤索引列 | Chosen | Cause |
---|---|---|---|---|---|
idx_status_create_time | Index Range Scan | 98518 | status AND create_time | True | Cost低 |
idx_create_time_status | Index Range Scan | 98518 | create_time | False | Cost高 |
MySQL优化器是基于Cost的,COST主要包括IO_COST和CPU_COST,MySQL的CBO(Cost-Based Optimizer基于成本的优化器)总是选择Cost最小的作为最终的执行计划去执行,从上面的分析,CBO选择的是复合索引idx_status_create_time,因为该索引中的status和create_time都能参与了数据过滤,成本较低;而idx_create_time_status只有create_time参数数据过滤,status被忽略了,其实CBO将其简化为单列索引idx_create_time,选择性没有复合索引idx_status_create_time好。
复合索引设计原则
- 将范围查询的列放在复合索引的最后面,例如idx_status_create_time。
- 列过滤的频繁越高,选择性越好,应该作为复合索引的前导列,适用于等值查找,例如idx_user_id_status。
这两个原则不是矛盾的,而是相辅相成的。
跳跃索引
一般情况下,如果表users有复合索引idx_status_create_time,我们都知道,单独用create_time去查询,MySQL优化器是不走索引,所以还需要再创建一个单列索引idx_create_time。用过Oracle的同学都知道,是可以走索引跳跃扫描(Index Skip Scan),在MySQL 8.0也实现Oracle类似的索引跳跃扫描,在优化器选项也可以看到skip_scan=on。
| optimizer_switch |use_invisible_indexes=off,skip_scan=on,hash_join=on |
适合复合索引前导列唯一值少,后导列唯一值多的情况,如果前导列唯一值变多了,则MySQL CBO不会选择索引跳跃扫描,取决于索引列的数据分表情况。
mysql> explain select id, user_id,status, phone from users where create_time >='2021-01-02 23:01:00' and create_time <= '2021-01-03 23:01:00'; +----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+---- | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+------+---------------+------+---------+------+--------+----------+---- | 1 | SIMPLE | users | NULL | range | idx_status_create_time | idx_status_create_time | NULL | NULL | 15636 | 11.11 | Using where; Using index for skip scan|
也可以通过optimizer_switch='skip_scan=off’来关闭索引跳跃扫描特性。
总结
本位为大家介绍了MySQL中的索引,包括聚集索引和辅助索引,辅助索引包含了主键id用于回表操作,同时利用覆盖索引扫描可以更好的优化SQL。
同时也介绍了如何更好做MySQL索引设计,包括前缀索引,复合索引的顺序问题以及MySQL 8.0推出的索引跳跃扫描,我们都知道,索引可以加快数据的检索,减少IO开销,会占用磁盘空间,是一种用空间换时间的优化手段,同时更新操作会导致索引频繁的合并分裂,影响索引性能,在实际的业务开发中,如何根据业务场景去设计合适的索引是非常重要的,今天就聊这么多,希望对大家有所帮助。
【推荐:mysql视频教程】
以上がMySQL インデックスをより効率的にするにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









次の手順でphpmyadminを開くことができます。1。ウェブサイトコントロールパネルにログインします。 2。phpmyadminアイコンを見つけてクリックします。 3。MySQL資格情報を入力します。 4.「ログイン」をクリックします。

MySQLはオープンソースのリレーショナルデータベース管理システムであり、主にデータを迅速かつ確実に保存および取得するために使用されます。その実用的な原則には、クライアントリクエスト、クエリ解像度、クエリの実行、返品結果が含まれます。使用法の例には、テーブルの作成、データの挿入とクエリ、および参加操作などの高度な機能が含まれます。一般的なエラーには、SQL構文、データ型、およびアクセス許可、および最適化の提案には、インデックスの使用、最適化されたクエリ、およびテーブルの分割が含まれます。

データベースとプログラミングにおけるMySQLの位置は非常に重要です。これは、さまざまなアプリケーションシナリオで広く使用されているオープンソースのリレーショナルデータベース管理システムです。 1)MySQLは、効率的なデータストレージ、組織、および検索機能を提供し、Web、モバイル、およびエンタープライズレベルのシステムをサポートします。 2)クライアントサーバーアーキテクチャを使用し、複数のストレージエンジンとインデックスの最適化をサポートします。 3)基本的な使用には、テーブルの作成とデータの挿入が含まれ、高度な使用法にはマルチテーブル結合と複雑なクエリが含まれます。 4)SQL構文エラーやパフォーマンスの問題などのよくある質問は、説明コマンドとスロークエリログを介してデバッグできます。 5)パフォーマンス最適化方法には、インデックスの合理的な使用、最適化されたクエリ、およびキャッシュの使用が含まれます。ベストプラクティスには、トランザクションと準備された星の使用が含まれます

MySQLは、そのパフォーマンス、信頼性、使いやすさ、コミュニティサポートに選択されています。 1.MYSQLは、複数のデータ型と高度なクエリ操作をサポートし、効率的なデータストレージおよび検索機能を提供します。 2.クライアントサーバーアーキテクチャと複数のストレージエンジンを採用して、トランザクションとクエリの最適化をサポートします。 3.使いやすく、さまざまなオペレーティングシステムとプログラミング言語をサポートしています。 4.強力なコミュニティサポートを提供し、豊富なリソースとソリューションを提供します。

Apacheはデータベースに接続するには、次の手順が必要です。データベースドライバーをインストールします。 web.xmlファイルを構成して、接続プールを作成します。 JDBCデータソースを作成し、接続設定を指定します。 JDBC APIを使用して、接続の取得、ステートメントの作成、バインディングパラメーター、クエリまたは更新の実行、結果の処理など、Javaコードのデータベースにアクセスします。

DockerでMySQLを起動するプロセスは、次の手順で構成されています。MySQLイメージをプルしてコンテナを作成および起動し、ルートユーザーパスワードを設定し、ポート検証接続をマップしてデータベースを作成し、ユーザーはすべての権限をデータベースに付与します。

CentOSにMySQLをインストールするには、次の手順が含まれます。適切なMySQL Yumソースの追加。 yumを実行して、mysql-serverコマンドをインストールして、mysqlサーバーをインストールします。ルートユーザーパスワードの設定など、MySQL_SECURE_INSTALLATIONコマンドを使用して、セキュリティ設定を作成します。必要に応じてMySQL構成ファイルをカスタマイズします。 MySQLパラメーターを調整し、パフォーマンスのためにデータベースを最適化します。

WebアプリケーションにおけるMySQLの主な役割は、データを保存および管理することです。 1.MYSQLは、ユーザー情報、製品カタログ、トランザクションレコード、その他のデータを効率的に処理します。 2。SQLクエリを介して、開発者はデータベースから情報を抽出して動的なコンテンツを生成できます。 3.MYSQLは、クライアントサーバーモデルに基づいて機能し、許容可能なクエリ速度を確保します。
