PostgreSQL でも 9.2 から インデックス・オンリー・スキャンが使えるようになっています。
この機能は データを取得する際に、インデックスだけで事足りる場合は インデックスのみを使用するというものです。 Oracle では昔からありましたが PostgreSQL では 9.2 から実装されました。
通常は、検索にインデックスを使用しても、テーブルからデータを取得するために 別の領域(ヒープ)を読みに行くわけですが、これが不要になるためパフォーマンスの向上に かなり期待できる部分があります。
ただ、PostgreSQLは追記型のデータベースなので インデックスだけでは 古いデータかどうか判断できないため、インデックス・オンリー・スキャンの実装は 難しいとされていました。 これを 8.4 でバキュームのため?に追加された ビジビリティマップ というデータを使って「インデックスだけで大丈夫か」を判断しているそうです。
なので、インデックス・オンリー・スキャンといっても、場合によってはテーブルのデータを読みに行く必要があります。 更新が多いテーブルでは難しいかもしれません。
三焦経だけでもありがたいですし、ビジビリティマップが綺麗に?なるようにバキュームも重要です。
実行計画を見ると次のようになります。
( field1 がテーブルの主キー)
psql=# EXPLAIN psql-# SELECT field1 FROM table1 psql-# WHERE field1 > 300000 Index Only Scan using table1_pkey on table1 (cost=0.43.. Index Cond: (field1 > 300000)
Index Only Scan と出力されます。
FOR コマンドは処理を繰り返すことができます。
次のサンプルは、aaaa.txt の内容を行ごとに ダブルクォーテーションで囲んで出力しています。
C:\> FOR /F %I IN (aaaa.txt) DO @ECHO "%I" >> bbbb.txt
これは次のように書くことができます。
C:\> (FOR /F %I IN (aaaa.txt) DO @ECHO "%I") > bbbb.txt
こうすることで、ファイルを空にする処理が不要になったり 処理の速度が上がったりします。
最近は PostgreSQL の機能も充実してきましたが Oracle にはまだまだ独自の機能が残っています。
今回は、前回やったマルチテーブル・インサートについて。
次のように INSERT文をまとめることができます。
SQL> INSERT ALL 2 INTO table1 (field1, field2) VALUES ('xxxxx1', 'xxxxxxxxx') 3 INTO table1 (field1, field2) VALUES ('xxxxx2', 'xxxxxxxxx') 4 INTO table1 (field1, field2) VALUES ('xxxxx3', 'xxxxxxxxx') 5 SELECT * FROM DUAL;
まとめるだけでなく複数のテーブルに INSERT できます。
SQL> INSERT ALL 2 INTO table1 (field1, field2) VALUES ('xxxxx1', 'xxxxxxxxx') 3 INTO table2 (field1, field2) VALUES ('xxxxx2', 'xxxxxxxxx') 4 INTO table3 (field1, field2) VALUES ('xxxxx3', 'xxxxxxxxx') 5 SELECT * FROM DUAL;
文末の DUAL に気づいたでしょうか?
5 SELECT * FROM DUAL;
ここにはテーブルや福問い合わせを指定することができます。
つまり 次のようなことができてしまうわけです。
SQL> INSERT ALL 2 INTO table1 (field1, field2) VALUES (fieldA, fieldB) 3 INTO table2 (field1, field2) VALUES (fieldA, fieldC) 4 INTO table3 (field1, field2) VALUES (fieldA, fieldD) 5 SELECT * FROM table4;
さらに条件も指定することができます。
SQL> INSERT ALL 2 WHEN fieldB < 10 THEN 3 INTO table1 (field1, field2) VALUES (fieldA, fieldB) 4 WHEN fieldC < 10 THEN 5 INTO table2 (field1, field2) VALUES (fieldA, fieldC) 6 WHEN fieldD < 10 THEN 7 INTO table3 (field1, field2) VALUES (fieldA, fieldD) 8 SELECT * FROM table4;
やっぱり Oracle は恐ろしいですね。
PostgreSQL や MySQL では次のように INSERT 文で 複数行を指定することができます。
psql=# INSERT INTO table1 (field1, field2) psql-# VALUES ('xxxxx1', 'xxxxxxxxx') psql-# , ('xxxxx2', 'xxxxxxxxx') psql-# , ('xxxxx3', 'xxxxxxxxx');
Oracle ではこの書き方ができません。
以下のように書きます。
SQL> INSERT ALL 2 INTO table1 (field1, field2) VALUES ('xxxxx1', 'xxxxxxxxx') 3 INTO table1 (field1, field2) VALUES ('xxxxx2', 'xxxxxxxxx') 4 INTO table1 (field1, field2) VALUES ('xxxxx3', 'xxxxxxxxx') 5 SELECT * FROM DUAL;
単に INSERT文をまとめただけのようですが この書き方は、異なるテーブルでもまとめることができます。 マルチテーブル・インサート と言うのですが 単に INSERT をまとめるだけではありません。
詳しくは次回。
コマンドプロンプトの DIR コマンドで ファイルだけを出力するときは 「/A」オプションで「ディレクトリ以外」を指定します。
C:\> DIR /A:-D
海外の顔文字みたいになってますが 「D」がディレクトリで、「-」が〇〇以外になります。
コロンは省略することができます。
C:\> DIR /A-D
「/B」オプションを付けてファイル名だけ、 なんてこともできます。
C:\> DIR /A:-D /B