• ベストアンサー

800万件のテーブル読み込みについて

oracle10G(10.2.0.1)をWin2003 SP2環境で使用しています。 あるテーブル(Aテーブル)のデータ量が800万件あり、そのテーブルを読み込むSQL(B.SQL)が4分程度かかっていました。 ある日、Aテーブルの項目名を変更することになりましたので、すべてのデータをCSV形式で保存し、テーブルをdropcreate後にsqlローダーにてインポートしたところ、B.SQLが15分かかるようになってしまいました。 B.SQLは、項目名を変えただけで、インデックスも削除する前と同じ状態にしてます。 どこから調査すればよいのでしょうか? よろしくお願いいたします。

  • Oracle
  • 回答数5
  • ありがとう数5

質問者が選んだベストアンサー

  • ベストアンサー
  • uresiiwa
  • ベストアンサー率45% (49/107)
回答No.5

統計について言及されていますが、B.SQLの実行計画を確認することも重要です。現状とあわない統計に基づいて実行計画を立てていた場合、非効率な実行計画が表示されていたはずです。(800万行もあるのにROWSが1となるなど) DBMS_STATSで解決したら良いですが、しなかった場合は、「コストベースで立てたプランが悪い実行計画となってしまった」ということが考えられます。コストベースだと、ほぼ同じデータでもある日突然遅くなることが十分考えられます。こっちの場合は、SQLにヒント句を組み込み、以前のような良い実行計画に誘導するやり方が考えられます。 もしくは、ダイレクパスロードのミスで主キーインデックスが壊れてしまい速度劣化するような場合などもありますが、いずれにしても、もしまだ遅かったら実行計画を出して分析してみてください。よく分からない時はここに実行計画を貼り付けたら皆さんがアドバイスくれるかと思います。

teatea
質問者

お礼

ご回答ありがとうございます。 explain plan により実行計画を確認してみます。

その他の回答 (4)

  • DB_eng
  • ベストアンサー率0% (0/1)
回答No.4

動的サンプリングが働いてしまっていること、 及び統計情報をとることが書かれているので、 1点、補足します。 統計情報の取得コマンドですが、ANALYZEではなく、 DBMS_STATS.GATHER_TABLE_STATSにて行ってください。 CBO(コストベースオプティマイザ)が使用する統計情報は ANALYZEコマンドではなく、DBMS_STATSが推奨されてます。 コマンドサンプルは、以下の通りです。 execute DBMS_STATS.GATHER_TABLE_STATS( ownname=> 'SCOTT', <== スキーマ名 tabname=> 'EMP' , <== テーブル名 estimate_percent=> DBMS_STATS.AUTO_SAMPLE_SIZE, <== 左記のままか、1~100までの値。AUTOはORACLEまかせ、100であればより正確な統計値が得られる cascade=> TRUE, <== その表に作成されている索引も取得 degree=> null <== 並列度。CPUが複数ある場合、指定すると取得時間が短縮される );

teatea
質問者

お礼

御回答ありがとうございます。 DBMS_STATSコマンドを実行してみます。

  • 3rd_001
  • ベストアンサー率66% (115/174)
回答No.3

まず、現状の実行計画をとりましょう。 アナライズは、実行計画を取ってからやりましょう。 でないと、どう変わったのかが判断できません。 また、今回は10gですので、現状がどうなっているかも調査してから対策を立てたほうが良いです。 もしかしたら、自動統計が取られているかもしれませんし、動的サンプリングで動いているのかもしれませんし、デフォルトの統計でうごいているかもしれません。 ※Oracleの設定次第ですので、調べないとわかりません。 統計については以下を読んでから実施した方がよいです。 http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/server.102/B19207-02/stats.htm

teatea
質問者

お礼

ご回答ありがとうございます。 早速実行してみます。

  • mako_sea
  • ベストアンサー率47% (62/130)
回答No.2

オラクルの統計情報は ANALYZEコマンドで取得するようです。 ただしこの統計情報更新で改善するかは、 オプティマイザの設定にもよると思われます。

参考URL:
http://itnavi.com/totteORA/Tips21.asp
teatea
質問者

お礼

御回答ありがとうございます。 analyzeコマンドを実行してみます。

  • wolf03
  • ベストアンサー率22% (241/1086)
回答No.1

コストベース検索である以上当然の事象です。 データを一気に入れたため、コスト最適化する統計情報が無い状態ですので遅いのです。 統計情報を何とかしない限り無理ですね。

teatea
質問者

お礼

御回答ありがとうございます。 統計情報を何とかするというのは、しばらく実行を繰り返してから 再度統計情報を取得するということでしょうか?

関連するQ&A

  • テーブルの作り方で困っています

    Oracle10gを使っています。 項目の順番がバラバラなcsvのデータを並べ換えてテーブルに登録したいのですが、 項目数はcsvによって違っていて、テーブルに登録する項目の数もcsvによって変わります。 例) AAA.csvの場合 元々は1,2,3,4,5,6の順番で項目が並んでいるが、登録する項目と順番は→3,1,2,4,5 BBB.csvの場合 元々は1,2,3,4,5,6の順番で項目が並んでいるが、登録すると項目と順番は→2,3,1,5,4,6 (AAA.csvとは違って、6番目の項目もテーブルに登録したい) といった感じです。 登録するテーブルはデータをプールする場所で、本登録するテーブルにこのテーブルのデータを移したら移し元のデータを消そうと思っています。 登録する側のテーブルの項目数がはっきりと決められないので、毎回テーブルをドロップ→違う項目数で再作成しようかとも思ったのですが、複数の人がこの処理を行いたい場合はやっぱりやめておいたほうがいいですよね? 分かり難い質問で申し訳ありません…。 何か良い知恵がありましたら、ご教授願います。 よろしくお願いします。

  • SQL*LoaderでCSVから指定した列のみインポートしたい。

    SQL*Loaderを用いてOracleのテーブルにデータを格納 しようと思っています。 格納するデータはカンマ区切りのCSVファイルです。 入力CSVファイルは他テーブル用のファイルなので、 ローダーで落とし込むテーブルとは列数が異なります。 ですので、「CSVの5列目の値をテーブルのAA_NOというフィールドに 格納する。ということが可能なのでしょうか?」 CSVファイルのある行が a,b,c,d,e,f というデータの場合、テーブルには a,e,f とインポートしたいのです。 よろしくお願いします。

  • テーブルデータのインポートについて

    バージョンはAccess2003です。 テーブルAとテーブルBがあります。 CSVからデータをインポートし、全データがテキスト型で保存されています。 テーブルBには最終的にデータを保存したいフィールドプロパティが定義されています。 VBを使ってテーブルAからテーブルBにインポートしたいと思っています。 テーブルAのデータをテーブルBの定義に合うように加工するにはどうすればいいのでしょうか? アドバイスよろしくお願いします。

  • コラム名でテーブルを検索できますか?

    SQL & ORACLE初心者です。最近、セレクト文を使って、テーブル内のデータを取り出すことができるようになりましたが、逆にコラム名からテーブルを検索することはできるでしょうか。 例えば、TABLE_A内のコラムの中にCOLUMN_Aという名前のコラムがあるとして、このコラムが他のテーブルでも使われているかどうか、いるとしたらどのテーブルかを知りたいのです。また、COLUMN_Aと別のCOLUMN_B(それぞれが単独で記載されているテーブル名はわかっているとします)が一緒にある一つのテーブルで使われているかどうか、またそのテーブル名を知りたいときには、どのようなSQLを書けばよいでしょうか。 DBAやその他DBを構築するための知識をお持ちの方、ご回答をお待ちしています。

  • テーブルのマッチングについて

    ORACLE10gを使用しています。 AとB同じレイアウト(キーも同じ)のテーブルがあります。 この2つのテーブルを比較して、 (1)Aテーブルのみにあるもの:1レコードCテーブルに追加 (2)Bテーブルのみにあるもの:1レコードCテーブルに追加 (3)A、B両方にあるもの:2レコードCテーブルに追加 上記に該当するレコードをCテーブルにINSERTしたいです。 実は、Cテーブルに項目が1つ追加されまして「区分」を書く必要があります。 どのパターン((1)か(2)か(3))でINSERTしたデータかです。 (1):1、(2):2、(3):3をセットする どのようにSQLを作成すると実現できるのでしょうか? ご指導よろしくおねがいします。

  • CSVファイルをテーブルにインポートする

    1行目が項目名のCSVファイルをテーブルにインポートするため Private Sub CSVインポート_Click() DoCmd.TransferText acImportDelim, , "ブランド", "J:\ブランド.TXT" MsgBox ("CSVファイルインポート完了") End Sub を実行すると、f1,f2のフィールドがありませんとメッセージがあり F1,F2 のフィールドを追加し再度実行するとデータは f1,f2に入り 項目名もデータとして入っています。 1行目は項目名と宣言する設定はありますか。 よろしくお願いいたします。

  • 二つのテーブルから呼び出すには?

    いつもお世話になります。 現在MySQLのAというテーブルとBというテーブル2つのテーブルがあります。 AとBは共に中のフィード名・フィールド数は全く同じで違う別々のサイトを運営しているためテーブルを分けてありますが、実質同じサーバーの中にあり「同じ形のテーブルで名前が異なる2つのテーブル」という状況です。 これをSQLでそれぞれ呼び出し、管理画面で最終的にひとつに表示させたいのですが良い方法はありませんでしょうか? $SQL .= " FROM "; $SQL .= " Aテーブル AS a,Bテーブル AS b"; ・・・ という形で呼び出していこうと思ったのですが最終的にAB両方のデータを出力するところで手がなくなってしまいました・・・。 (例)A、Bにそれぞれ注文データが入っていて、それを最終的には1つのものとして表示させたいです。 なかなか文字だけでは伝わりにくくてすいません・・・。 補足要求などあれば難なくお申し付けください。 何卒よろしくお願い致します。

    • ベストアンサー
    • PHP
  • 2つのテーブル結合

    Oracle10g使用しています。 テーブルAとテーブルBを結合させてデータを取得したいと思っています。 [テーブルA] ID name 1 A 2 B 3 C 4 D [テーブルB] ID SEQ VALUE 1 1 111 2 1 222 2 2 333 3 1 444 4 1 555 4 2 666 4 3 777 テーブルAのキーは[ID]、テーブルBのキーは[ID,SEQ]です。 この二つを連結して以下のように出力したいと思っています。 ID SEQ NAME VALUE 1 1 A 111 2 2 B 333 3 1 C 444 4 3 D 777 テーブルBのデータは同じIDのうち最大のSEQのものを取得したいのですが よいSQLが思いつきません。 よい方法があればご教授ください。 よろしくお願いいたします。

  • オラクルのUPDATEで複数テーブル

    見ていただいてありがとうございます。 どなたか、方法がお分かりになる方、 ご教授いただけるよう宜しく御願いいたします。 ORACLEのSQL_PLUSを使用して以下のような SQLを実行するとエラーとなります。 UPDATE テーブル名1 , テーブル名2 SET テーブル名1.項目A = '2' , テーブル名1.項目B = '02' , テーブル名1.項目C = テーブル名2.項目A 当方、ACCESSとSQLサーバーでSQLの経験が若干あり、 そちらではこの記述方法で正常実行されるのですが、 オラクルでの記述方法がよくわかりません。 ネット等を利用し調べたのですが、打開策が見つからず、質問させていただこうと思った次第です。 どうか宜しく御願いいたします。

  • テーブルA、Bで、項目の重複の有無確認をしたい

    CSVファイルからレコードをインポートしたテーブルAがあります。 インポートした後に処理済みレコードを累積収納するテーブルBがあります。 インポート後、テーブルAのレコードをもとに処理してCSVファイルをエクスポートして、処理済みレコードをテーブルBに移しています。 テーブルA、同Bには「日付」項目があります。 テーブルAにインポート後、処理を実行する際に、テーブルBの日付とテーブルAの日付の重複がないことを比較チェックし、もし重複があればメッセージを出して処理を中断させたいのです。 If~Then~Else、IsNull、DLoolup関数を使って試みましたが、うまくいきません。 VBAでどのような記述をすればいいでしょうか?