2

ここでの状況では、多くの行で構成されるOracle DBからレポートを生成しようとしています。現在、クエリ時間は約5分で、クエリ時間を短縮する可能性のあるクエリを変更する方法があるかどうかを確認したいと思います。

SELECT ib1.id as InvoiceNumber,
ib1.shipmentno as ShipmentNumber,
ib1.ref as ConsignorRef, 
cons1.name as ConsName,
ib1.consolidation_type as ShipmentType, 
to_char(ib1.custom_field12, 'YYYYMMDDhhmmss') as InvoiceDate, 
ib1.reg_time as HousingDate, 
ib1.list_add_time as Pickup, 
ib1.confirm_date as Date, 
ex1.stat_date as Timestamp, 
ib1.date_prefered as ETA, 
ib1.field7 as Housing, 
ib1.countrycode as Country
FROM Invoice ib1,
     ek_export ex1,
      ek_cons cons1
WHERE ib1.ex_id=124
AND ib1.id=ex1.ib_id
AND ex1.state_type='DELIVERED'
AND ib1.cons_id=cons1.id
AND ex1.ex_id=124
AND trunc(ib1.reg_time) BETWEEN to_date('2009-01-01', 'YYYY-MM-DD') AND to_date('2010-01-01', 'YYYY-MM-DD')
ORDER BY ib1.id

任意のヒント?

4

4 に答える 4

5

You have to check that your query uses indexes.

I think you'll have to index :

  • ex1.ib_id
  • ex1.state_type
  • ib1.cons_id
  • ex1.ex_id
  • ib1.reg_time

また、クエリ条件での関数の使用を避け、関数の結果を直接入れるようにしてください

  • to_date('2009-01-01', 'YYYY-MM-DD') 可能であれば結果に置き換え
  • trunc(ib1.reg_time)、すでに「切り詰められた」値を格納しようとします

次に、Ingoの回答で述べたように参加して、参加をより適切に制御します。

最後に、結果を ib1.id で並べ替えますが、必要ですか? そうでない場合は、order 句を削除します。

このOracleのドキュメントを確認してください。クエリの分析についてです。 http://docs.oracle.com/cd/B10500_01/server.920/a96533/ex_plan.htm

于 2013-02-15T08:53:02.827 に答える
2

クエリを分析する必要があります。実行計画を確認し、参加している各テーブルで作成されたインデックスを確認することもできます。

経験則では、where 句と order by 句に参加する列にインデックスを作成する必要があります。

別の同様の質問がここにあります: Making my SQL Query more effective

于 2013-02-15T08:49:01.410 に答える
0

クエリは最初にすべてのテーブルに対してクロス結合を行い、次にwhere句で膨大な結果をフィルタリングします...内部結合を使用して、最初に重要な行のみを選択します...のように

...
from invoice ib1 
join ek_export ex1 on ib1.id = ex1.ib_id
join ek_cons cons1 on ib1.cons_id = cons1.id
...
于 2013-02-15T08:48:43.790 に答える
0

クエリには、クエリ自体とフェッチの 2 つのステップがありますが、フェッチは圧縮できないと思います。各ステップの時間を教えてください。(mysql-worbench は両方の情報を提供します)

于 2013-02-15T08:46:12.217 に答える