MySQLにおける結合アルゴリズムの実装原理の分析

MySQLにおける結合アルゴリズムの実装原理の分析

MySQL には、有名なネスト ループ結合という結合アルゴリズムが 1 つだけあります。他の多くのデータベースで提供されているハッシュ結合やソート マージ結合はありません。名前が示すように、ネスト ループ結合は実際には駆動テーブルの結果セットをループの基本データとして使用し、結果セットのデータをフィルタリング条件として使用して次のテーブルのデータを 1 つずつクエリし、結果をマージします。結合に 3 番目のテーブルが含まれる場合、最初の 2 つのテーブルの結合結果セットがループの基本データとして使用され、ループ クエリ条件を通じて 3 番目のテーブルでデータが再度クエリされる、というように繰り返します。

例と図を使って説明しましょう。後ほど、個人的なデータベース テスト環境での例 (MySQL が提供したものではなく、自分で設計したもの) を使用して、データベース内の 3 つのテーブルの結合クエリについて説明します。

注: ここでのコンテンツの一部は MySQL バージョン 5.1.18 以降にのみ反映されるため、このテストで使用されている MySQL バージョンは 5.1.26 です。

テーブル構造:

 1 sky@localhost : 例 11:09:32> show create table user_group\G
2
3 **************************** 1. 行 ****************************
4
5 テーブル: user_group
6
7 テーブルの作成: CREATE TABLE `user_group` (
8
9 `user_id` int(11) NULLではない、
10
11 `group_id` int(11) NOT NULL,
12
13 `user_type` int(11) NOT NULL,
14
15 `gmt_create` 日時 NOT NULL、
16
17 `gmt_modified` 日時がNULLではない、
18
19 `ステータス` varchar(16) NOT NULL,
20
21 キー `idx_user_group_uid` (`user_id`)
22
23) エンジン=InnoDB デフォルト文字セット=utf8
24
25 セット内 1 行 (0.00 秒)
26
27 sky@localhost : 例 11:10:32> show create table group_message\G
28
29 **************************** 1. 行 ****************************
30
31 テーブル: group_message
32
33 テーブルの作成: CREATE TABLE `group_message` (
34
35 `id` int(11) NOT NULL AUTO_INCREMENT,
36
37 `gmt_create` 日時 NOT NULL、
38
39 `gmt_modified` 日時 NOT NULL、
40
41 `group_id` int(11) NULLではない、
42
43 `user_id` int(11) NULLではない、
44
45 `author` varchar(32) NOT NULL,
46
47 `subject` varchar(128) NOT NULL,
48
49 主キー (`id`)、
50
51 キー `idx_group_message_author_subject` (`author`,`subject`(16))、
52
53 キー `idx_group_message_author` (`author`),
54
55 キー `idx_group_message_gid_uid` (`group_id`,`user_id`)
56
57 ) エンジン=InnoDB AUTO_INCREMENT=97 デフォルト文字セット=utf8
58
59 セット内 1 行 (0.00 秒)
60
61 sky@localhost : 例 11:10:43> show create table group_message_content\G
62
63 **************************** 1. 行 ****************************
64
65 テーブル: グループメッセージコンテンツ
66
67 テーブルの作成: CREATE TABLE `group_message_content` (
68
69 `group_msg_id` int(11) NULLではない、
70
71 `content` テキストがNULLではない、
72
73 キー `group_message_content_msg_id` (`group_msg_id`)
74
75 ) エンジン=InnoDB デフォルト文字セット=utf8
76
77 セット内 1 行 (0.00 秒)

クエリは次のように使用します。

 1 m.subject msg_subject、c.content msg_contentを選択
2
3 ユーザーグループ g、グループメッセージ m、グループメッセージコンテンツ c から
4
5 ここで g.user_id = 1
6
7 かつ m.group_id = g.group_id
8
9 かつ c.group_msg_id = m.id


クエリ実行プランを見てみましょう。

1 sky@localhost : 例 11:17:04> explain select m.subject msg_subject, c.content msg_content
2
3 -> ユーザーグループ g、グループメッセージ m、グループメッセージコンテンツ c から
4
5 -> g.user_id = 1 の場合
6
7 -> かつ m.group_id = g.group_id
8
9 -> かつ c.group_msg_id = m.id\G
10
11 **************************** 1. 行 ****************************
12
13 id: 1
14
15 選択タイプ: シンプル
16
17 表: g
18
19 タイプ: ref
20
21 個の可能なキー: user_group_gid_ind、user_group_uid_ind、user_group_gid_uid_ind
22
23 キー: user_group_uid_ind
24
25 キーの長さ: 4
26
27 参照: 定数
28
29行: 2
30
31 追加:
32
33 ************************** 2. 行 ****************************
34
35 id: 1
36
37 選択タイプ: シンプル
38
39 表: m
40
41 タイプ: ref
42
43 個の可能なキー: PRIMARY、idx_group_message_gid_uid
44
45 キー: idx_group_message_gid_uid
46
47 キーの長さ: 4
48
49 参照: example.g.group_id
50
51 行: 3
52
53 追加:
54
55 ************************** 3. 行 ****************************
56
57 id: 1
58
59 選択タイプ: シンプル
60
61 表: c
62
63 タイプ: ref
64
65 個の可能なキー: idx_group_message_content_msg_id
66
67 キー: idx_group_message_content_msg_id
68
69 キーの長さ: 4
70
71 参照: example.m.id
72
73 行: 2
74
75 追加:

MySQL クエリ オプティマイザーが駆動テーブルとして user_group を選択していることがわかります。最初に、渡された条件 user_id を使用して、テーブルのインデックス user_group_uid_ind を介して const 条件のインデックス参照検索を実行します。次に、user_group テーブルからフィルターされた結果セットの group_id フィールドをクエリ条件として使用して、group_message でループ クエリを実行します。次に、user_group テーブルと group_message テーブルの結果セットの group_message id を条件として使用して、ループ クエリで group_message_content の group_msg_id と比較し、最終結果を取得します。特別なことは何もありません。後者は、前のものの結果セットを条件として参照します。実装プロセスは次の図で表すことができます。

次に、group_message_content を調整して idx_group_message_content_msg_id インデックスを削除し、その効果を確認します。

 1 sky@localhost : 例 11:25:36> group_message_content のインデックス idx_group_message_content_msg_id を削除します。
2
3 クエリは正常、96 行が影響を受けました (0.11 秒)
4
5 sky@localhost : 例 10:21:06> 説明
6
7 -> m.subject msg_subject、c.content msg_content を選択
8
9 -> ユーザーグループ g、グループメッセージ m、グループメッセージコンテンツ c から
10
11 -> g.user_id = 1 の場合
12
13 -> かつ m.group_id = g.group_id
14
15 -> かつ c.group_msg_id = m.id\G
16
17 ************************** 1. 行 ****************************
18
19 id: 1
20
21 選択タイプ: シンプル
22
23 表: g
24
25 タイプ: ref
26
27 個の可能なキー: idx_user_group_uid
28
29 キー: idx_user_group_uid
30
31 キーの長さ: 4
32
33 参照: 定数
34
35行: 2
36
37 追加:
38
39 **************************** 2. 行 ****************************
40
41 id: 1
42
43 選択タイプ: シンプル
44
45 テーブル: m
46
47 タイプ: ref
48
49 個の可能なキー: PRIMARY、idx_group_message_gid_uid
50
51 キー: idx_group_message_gid_uid
52
53 キーの長さ: 4
54
55 参照: example.g.group_id
56
57 行: 3
58
59 追加:
60
61 **************************** 3. 行 ****************************
62
63 id: 1
64
65 選択タイプ: シンプル
66
67 表: c
68
69 タイプ: ALL
70
71 可能なキー: NULL
72
73 キー: NULL
74
75 キー長さ: NULL
76
77 参照: NULL
78
79 行: 96
80
81 追加: where の使用; join buffer の使用

group_message_content テーブルへのアクセスが ref から ALL に変わっただけでなく、最後の行の Extra 情報も nothing から Using where; Using join buffer に変わったことがわかります。つまり、ref から ALL に変わったのは、使用できるインデックスがないため、当然フル テーブル スキャンが必要になるためであることは簡単に理解できます。また、Using where は、フル テーブル スキャンの後、取得する必要のあるコンテンツ フィールドは、where を使用してテーブル内のデータをフィルタリングすることによってのみ取得できるためでもあります。しかし、後に表示される Using join buffer とは何でしょうか。

MySQL には設定可能なパラメータ join_buffer_size があることはわかっています。ここでは、実際にこのパラメータによって設定されたバッファ領域を使用します。では、なぜ以前の実行計画では使用されなかったのでしょうか?

実際、Join Buffer は、Join タイプが ALL (例のように)、index、rang、または index_merge の場合にのみ使用できます。したがって、group_message_content テーブルの group_msg_id フィールドのインデックスを削除する前は、Join が ref タイプであるため、実行プランで Join Buffer が使用されることはありません。

Join Buffer を使用した後、次の図を使用して Join 完了プロセスを表すことができます。

<<:  SQL Server 2005 のデータ マイニング アルゴリズム拡張メソッド

>>:  マイクロソフトの面接アルゴリズムに関する 4 つの質問

ブログ    

推薦する

シリコンバレーの人工知能専門家:人類は20年以内に老化の束縛から解放されるかもしれない

現在、世界最高齢の人は、ギネス世界記録に認定された118歳の日本人老人、田中カネさんです。田中選手の...

ガートナーの調査によると、企業は来年AIプロジェクトを2倍に増やすと予想している。

世界有数の情報技術調査およびアドバイザリ企業であるガートナーによる最近の調査によると、現在人工知能 ...

Pytorch Geometric を使用したリンク予測コードの例

PyTorch Geometric (PyG) は、グラフ ニューラル ネットワーク モデルを構築し...

北京の自動運転路上試験、安全走行距離が300万キロ超え

IT Homeは5月30日、新華社通信が伝えたところによると、記者が29日に北京市インテリジェント車...

MITのロボット犬がまた進化しました。砂利や氷の上でも滑らずに走れます。今回は本当に犬と同じくらい安定しています

この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI)より許可を得て転載...

アリババには、1秒間に8人の弁護士を打ち負かした新しい技術者がいる

[[231585]] Alimeiの紹介:エッセイの添削、同時通訳、ポスター作成…人工知能技術は私た...

アンドリュー・ン:AIはビッグデータから「スモールデータ」に移行する時が来た

AI界の巨匠アンドリュー・ン氏が最近、新型コロナウイルスの検査で陽性反応を示し、多くのネットユーザー...

クロード3の「自己認識」事件が爆発、マスクはじっとしていられず、OpenAIにはバックアッププランがあることが明らかに

クロード3は発売されてから24時間以上経ちますが、今でも人々の認知をリフレッシュさせています。量子物...

...

人工知能の時代:知識を活用して人間関係を変える

[[428386]]ヘンリー・A・キッシンジャー、エリック・シュミット、ダニエル・ハッテンロッカーに...

5GとAIの強力な組み合わせは、どのような新たな機会をもたらすのでしょうか?

[[261281]]新興技術への投資家として、私は既存の市場を改善したり、新しい市場を創出したりで...

ChatGPT をベースにしたインテリジェントな顧客サービス アシスタント

導入従来の顧客サービス分野は、手作業に大きく依存し、データ集約的であることが特徴です。大量のユーザー...

2024年の8つの主要テクノロジートレンド

1. AIと機械学習を採用する人が増える人工知能 (AI) と機械学習 (ML) は単なる流行語では...

Google検索は非常に勤勉で、そのコアアルゴリズムは毎日変化しています

Googleの検索事業責任者アミット・シンガル氏は最近、Google+に記事を掲載し、過去1年だけで...

OpenAI がハッカーのグループチャットに潜入!盗まれたChatGPTは「Meow Meow GPT」に置き換えられました、ネットユーザー:まさに伝説的

ChatGPT がハッカーによって「ハッキング」された場合、OpenAI はどのように対応するのでし...