explain
[SQLite] SQLiteで実行計画を見てみよう その2ではテーブル結合の実行計画を取得して、nested loopの様子を見たけど、SQLiteではさらに詳細に内部の実行手順を見ることができる。今度はexplain query planではなく、explainを使う。
The SQLite Bytecode Engine
[SQLite] SQLiteで実行計画を見てみよう その2で実行したSQLにexplainをつけて、見てみよう。
sqlite> explain select Test1.id, Test2.id, Test1.name from Test1 ...> join Test2 on Test1.last_modified = Test2.last_modified; addr opcode p1 p2 p3 p4 p5 comment ---- ------------- ---- ---- ---- ------------- -- ------------- 0 Init 0 24 0 00 NULL 1 OpenRead 0 2 0 3 00 NULL 2 OpenRead 1 86 0 3 00 NULL 3 Rewind 0 22 0 00 NULL 4 Once 0 12 0 00 NULL 5 OpenAutoindex 2 2 0 k(2,B,) 00 NULL 6 Rewind 1 12 0 00 NULL 7 Column 1 2 2 00 NULL 8 Rowid 1 3 0 00 NULL 9 MakeRecord 2 2 1 00 NULL 10 IdxInsert 2 1 0 10 NULL 11 Next 1 7 0 03 NULL 12 Column 0 2 4 00 NULL 13 IsNull 4 21 0 00 NULL 14 SeekGE 2 21 4 1 00 NULL 15 IdxGT 2 21 4 1 00 NULL 16 Rowid 0 5 0 00 NULL 17 IdxRowid 2 6 0 00 NULL 18 Column 0 1 7 00 NULL 19 ResultRow 5 3 0 00 NULL 20 Next 2 15 0 00 NULL 21 Next 0 4 0 01 NULL 22 Close 0 0 0 00 NULL 23 Halt 0 0 0 00 NULL 24 Transaction 0 0 12 0 01 NULL 25 TableLock 0 2 0 Test1 00 NULL 26 TableLock 0 86 0 Test2 00 NULL 27 Goto 0 1 0 00 NULL
addr 25, 1, 3 を見ると、Test1が外側のループになっていて、addr 3-21がループ範囲になっていることがわかる。
addr 26, 2, 1 を見ると、Test2が内側のループになっていて、addr 6-11がループ範囲になっていることがわかる。
ただし、addr 4にOnceとあるようにaddr 5-11は初回のみ実行されて、ここでAutomatic Indexが構築される。
このため、実際の毎回実行される内部ループはaddr12-20となる。
検索条件ありの場合
今度は where Test2.name = 'HBnod4xm' をつけたバージョンを実行してみよう。sqlite> explain select Test1.id, Test2.id, Test1.name from Test1 ...> join Test2 on Test1.last_modified = Test2.last_modified ...> where Test2.name = 'HBnod4xm'; addr opcode p1 p2 p3 p4 p5 comment ---- ------------- ---- ---- ---- ------------- -- ------------- 0 Init 0 22 0 00 NULL 1 OpenRead 1 86 0 3 00 NULL 2 OpenRead 2 115 0 k(2,,) 02 NULL 3 OpenRead 0 2 0 3 00 NULL 4 String8 0 1 0 HBnod4xm 00 NULL 5 SeekGE 2 18 1 1 00 NULL 6 IdxGT 2 18 1 1 00 NULL 7 Seek 2 0 1 00 NULL 8 Rewind 0 17 0 00 NULL 9 Column 0 2 2 00 NULL 10 Column 1 2 3 00 NULL 11 Ne 3 16 2 (BINARY) 51 NULL 12 Rowid 0 4 0 00 NULL 13 IdxRowid 2 5 0 00 NULL 14 Column 0 1 6 00 NULL 15 ResultRow 4 3 0 00 NULL 16 Next 0 9 0 01 NULL 17 Next 2 6 1 00 NULL 18 Close 1 0 0 00 NULL 19 Close 2 0 0 00 NULL 20 Close 0 0 0 00 NULL 21 Halt 0 0 0 00 NULL 22 Transaction 0 0 12 0 01 NULL 23 TableLock 0 86 0 Test2 00 NULL 24 TableLock 0 2 0 Test1 00 NULL 25 Goto 0 1 0 00 NULL
addr 2でオープンした範囲を5-17でループしている。
明示的には書かれていないけど、addr 2のP2の115がTest2.nameのインデックスを指しているようだ。
内側のループはaddr 8-16になる。
こちらはRewindでテーブルをscanしているのがわかる。
こうして見れば、nested loopがまさにnested loopだというのがよくわかるね。
0 件のコメント:
コメントを投稿