1

私はこのクエリを持っています:

  SELECT B.BILL_BALANCE,
       B.PRIME_UID,
       home.IDENT,
       PRESENT.ACC_LOGIN,
       PRESENT.ACCOUNT_NAME2,
       eq .ACCESS_NO AS PHONE,
           adres.DISP_STREET_NAME,
           B.BILL_DT
FROM addresses adres ,
     BILL_HISTORY B
LEFT JOIN eq eq ON eq.ACCOUNT_NO = B.ACCOUNT_NO
JOIN sec PRESENT ON B.ACCOUNT_NO = PRESENT.ACCOUNT_NO
JOIN sec_text home ON home.ACCOUNT_NO = B.ACCOUNT_NO
WHERE eq.STATUS_CD = 'CU'
  AND (B.BILL_TP_CD='CB'
       OR B.BILL_TP_CD='FB')
  AND (PRESENT.bill_addr_UID=adres.PRIME_UID
       OR PRESENT.COMPANY_REG_ADDR_UID=adres.PRIME_UID)
  AND B.BILL_PAID_DT IS NULL
  AND B.BILL_DT >= to_date('2011-07-01')
  AND B.BILL_DT <= to_date('2011-07-02')
  AND rownum <=1000
GROUP BY B.PRIME_UID,
         B.BILL_BALANCE,
         home.IDENT,
         PRESENT.ACC_LOGIN,
         PRESENT.ACCOUNT_NAME2,
         eq .ACCESS_NO,
             adres.DISP_STREET_NAME,
             B.BILL_DT

このエラーが発生した後、B.PRIME_UIDで「groupby」する必要があります。

    [code] => 979
    [message] => ORA-00979: not a GROUP BY expression
    [offset] => 8

すべての列を「groupby」に追加しましたが、機能します。

このクエリは「rownum」でのみ機能します。「rownum」を削除しようとすると、データへのアプローチが長すぎます。50分を超えています。

行数を使用せずにSQLを書き換えるにはどうすればよいですか?
ありがとう。

表の概算データは100000を超えています。

更新*
「ExplainPLANFOR」が機能しませんでした。

Array
(
    [error] => 1
    [error text] => not found
    [sql] => EXPLAIN PLAN FOR
SELECT  B.BILL_BALANCE,B.PRIME_UID,home.IDENT,PRESENT.ACC_LOGIN,PRESENT.ACCOUNT_NAME2,eq .ACCESS_NO as PHONE,adres.DISP_STREET_NAME,B.BILL_DT
FROM addresses adres ,BILL_HISTORY B 
     LEFT JOIN eq eq ON eq.ACCOUNT_NO = B.ACCOUNT_NO 
     JOIN   sec PRESENT
         ON B.ACCOUNT_NO = PRESENT.ACCOUNT_NO
     JOIN sec_text home
         ON home.ACCOUNT_NO = B.ACCOUNT_NO



WHERE  
eq.STATUS_CD = 'CU'  AND
 (B.BILL_TP_CD='CB' OR B.BILL_TP_CD='FB') 
AND  (PRESENT.bill_addr_UID=adres.PRIME_UID OR PRESENT.COMPANY_REG_ADDR_UID=adres.PRIME_UID) 
AND B.BILL_PAID_DT IS NULL 
 AND B.BILL_DT >= to_date('2011-07-01') 
 AND B.BILL_DT <= to_date('2011-07-02') 

AND rownum <=10
GROUP BY B.PRIME_UID,B.BILL_BALANCE,home.IDENT,PRESENT.ACC_LOGIN,PRESENT.ACCOUNT_NAME2,eq .ACCESS_NO,adres.DISP_STREET_NAME,B.BILL_DT
)
4

3 に答える 3

3

latrep.ADDRESSESとBILL_HISTORYの間にデカルト積があるだけでなく、クエリのパフォーマンスが低下する可能性が高いだけでなく、TO_DATE関数の日付形式を次の代わりに指定することを怠っています:AND B.BILL_DT> = to_date( '2011-07-01')

使用:AND B.BILL_DT> = to_date( '2011-07-01'、'YYYY-MM-DD')

rownum <= 10を指定して返されるレコードを制限するとすぐに戻りますが、それを削除するとパフォーマンスの問題が発生するという事実は、膨大な数のレコード(デカルト積)を返そうとしている、または実行プランに重大な問題があることを示しています。おそらく、大きなテーブルの完全なテーブル(または大きなインデックス範囲)スキャン。

いずれにせよ、Explainプランを生成できない場合にこれをテストする最良の方法は、クエリからテーブルBILL_HISTROYを一時的に削除して、パフォーマンスが向上するかどうかを確認することです。

これらの2つのテーブル間の結合を整理すると、間違いなく役立ちます。説明プランを入手してください。より明確な回答を提供できます。

于 2011-07-07T15:51:25.550 に答える
2

説明の計画がなければ、確かに言うのは難しいですが、問題はこれに関連していると思います:

FROM latrep.ADDRESSES adres ,
     BILL_HISTORY B

そこにデカルト積があります。結合条件がない場合、他のすべての結合に加えて、ADDRESSESのすべての行がBILL_HISTORYのすべての行に結合されます。それは永遠にかかるでしょう。後でこれを絞り込んでみますが、ORが原因で、いずれかの基準に一致する前に全表スキャンとデカルト積を実行する必要があると思われます。

  AND (SUB.bill_addr_UID=adres.PRIME_UID
       OR SUB.COMPANY_REG_ADDR_UID=adres.PRIME_UID)

クエリからBILL_HISTORYを完全に引き出して、パフォーマンスが大幅に向上するかどうかを確認してください。もしそうなら、それはおそらくあなたの問題があるところです。(次に、DBAにアクセスして、EXPLAIN PLANを機能させます。これは、このような問題を解決するために本当に必要です。)

于 2011-07-07T11:10:32.750 に答える
1

入会には忘れられた条件があると思います

latrep.ADDRESSES adres 

BILL_HISTORY B

そのため、時間がかかりすぎます。

また、select句(クエリの一部)には、groupby句にあるものだけを直接含めることができます。他の列でグループ化する必要がない/必要がない場合は、そこに配置しないでください。必要に応じて、max、min、avg、...の値に集計関数を使用する必要があります。

例えば

select date_in, 
       min(id) as ids_from, 
       max(id) as ids_to
  from table
 group by date_in;
于 2011-07-07T11:44:37.067 に答える