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 つの質問

ブログ    
ブログ    
ブログ    
ブログ    

推薦する

...

オペレーティング システムに関して、一般的に使用されているスケジューリング アルゴリズムをいくつ知っていますか?

オペレーティング システムには多くのスケジューリング アルゴリズムがあり、ジョブ スケジューリングに...

...

今日の人工知能は単なる「狭義のAI」なのでしょうか?

1956 年、若い数学助教授ジョン・マッカーシーが率いる科学者グループがニューハンプシャー州のダー...

機械学習から学習する機械まで、データ分析アルゴリズムにも優れた管理者が必要だ

[[177274]]写真は、IBM Big Data and Analytics のグローバル研究開...

人工知能は前例のないキャリア革命をもたらすだろう

最近、サンフランシスコでEatsaというアメリカンレストランが人気になっています! [[203610...

ソファがリモコンに変身、PCBが落書きに隠れる、MITの技術オタクのスマートホームはこんな感じ

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

韓国の通信事業者SKT、通信業界向け大規模AIモデルの開発のためOpenAIの競合企業に1億ドルを投資

大規模な AI モデルのトレンドは通信業界にも浸透しています。米国のAIスタートアップ企業Anthr...

初心者向けガイド: Numpy、Keras、PyTorch を使用した単純な線形回帰

[[433966]]図 1 に示すように、さまざまな種類の機械学習技術は、さまざまなカテゴリに分類で...

李開復:今後数年間、中国で最も収益性の高い仕事は何でしょうか?

1物語はAI熱狂の3つの波から始まる2017年、誰もが人工知能について語っていました。しかし、2度...

...

成功の秘訣: AIを活用したオンライン文書検証

[[410827]] [51CTO.com クイック翻訳]急速な技術開発と進歩の時代において、個人情...

AIは占いや顔分析ができるのか? 「IQ税」を払わないでください

「五十の大道あり、四十九は天から出たもの、人は一つを逃れる。」人々は未知のものに興味を持ち、その未知...