SQLiteでは、テーブルを作成するとROWID列が自動で生成されます。
このROWID列が無いテーブル(WITHOUT ROWID)を使用することで、パフォーマンスを向上できるケースがあり、以下ではその理由などについて記載しています。
目次
1. パフォーマンスが上がる理由
次のような商品テーブルがあるとします。
1 2 3 4 |
CREATE TABLE IF NOT product ( id TEXT PRIMARY KEY, // A00001, A00002 などの商品ID name TEXT // 商品名 ); |
このようなROWID列があるテーブルの場合、検索するB-treeが2つ作成されます。
1つめのB-Tree(ROWID検索)
ROWIDで検索するために使用されます。表のidやnameの実際の値は、ROWIDとペアでこのB-Treeに格納されます。
2つめのB-Tree(主キー検索)
主キー(id)で検索するために使用されます。主キーに紐つくROWID が格納されています。
仮に、主キー(id)で検索を行った場合、次の動作になります。
- 2つめのB-Treeを主キーで検索して、紐つくROWIDを取得
- 1つめのB-Treeを 1 で取得したROWIDで検索して、idやname列の実際の値を取得
このように、主キー列で検索をしますが、実際の値を持っているのは、ROWIDのB-Treeのため、2回 B-Tree を検索する必要があります。
また、データのインサート時にも2つのB-Treeをメンテするコストも必要になります。
そのため、WITHOUT ROWIDテーブル(ROWIDなしテーブル)では、ROWIDのB-Treeが不要になり、
- 主キーで検索すると 1回のB-Treeの検索で値を取得することができる
- B-Treeのメンテコストも低くなる
という理由から、パフォーマンスの向上が期待できます。
2. WITHOUT ROWIDテーブルの主な制約
WITHOUT ROWIDテーブルでは、ROWIDつきテーブルと異なり、主に以下の制約が適用されます。
- テーブルに主キー(PRIMARY KEY )が必要
- AutoIncrement が使用できない
- 主キーにNOT NULL制約がつく
1. テーブルに主キーが必要
ROWIDつきテーブルでは、ROWIDが一意な値のため、主キー制約は任意でした。
WITHOUT ROWIDテーブルでは、ROWIDが無いため明示的に行を一意に特定できる主キーを定義する必要があります。
2. AutoIncrement が使用できない
AutoIncrement機能は、ROWIDが存在することが前提で動作するため、WITHOUT ROWIDテーブルでは使用することができません。
AutoIncrementの詳細については、こちら(AutoIncrement の使用方法と注意すること)を参照してください。
3. 主キーにNOT NULL制約がつく
ROWIDつきのテーブルでは、過去の不具合との互換性のため、主キーにもNULLを登録することができました。
WITHOUT ROWIDテーブルでは、SQL標準の動作を行い、主キーにNULLを登録することはできません。
3. ROWIDつきテーブルを使用するケース
次の場合は、ROWIDつきテーブルの方が高速に動作する可能性があります。
- INTEGER PRIMARY KEY をもつテーブル
- テーブルの個々の行データが大きすぎない
1. INTEGER PRIMARY KEY をもつテーブル
INTEGER PRIMARY KEY 列は、ROWIDのエイリアスとして機能します。
そのため、INTEGER型の主キーをもつテーブルの場合は、ROWIDつきテーブルの方が早く動作する場合もあります。
なお、INTEGER PRIMARY KEY 列 を使用する際の注意事項は、こちら を参照してください。
2. テーブルの個々の行データが大きい
ページサイズを目安に、次に該当する場合は、ROWIDつきのテーブルの方が高速に動作する傾向があります。
ページサイズが1KiBの場合:50バイトを超える
ページサイズが4KiBの場合:200バイトを超える
4. WITHOUT ROWIDテーブルの作成方法
最後になりましたが、WITHOUT ROWIDテーブルは、通常のCREATE TABLE 文の末尾に、WITHOUT ROWID 句をつけることで作成することができます。
1 2 3 4 |
CREATE TABLE IF NOT product ( id TEXT PRIMARY KEY, // A00001, A00002 などの商品ID name TEXT // 商品名 ) WITHOUT ROWID; |
参考サイト