0

現在、このクエリの実行には約 30 秒かかります。

高速化する方法を知りたいのですが、どうすればよいのかわかりません。どんな助けでも素晴らしいでしょう。注意: 現時点では、データベースまたはその設計に実際の変更を加えることができません。

SELECT top 1 v.[address], v.[address2], v.[city], v.[state_prov_id],v.[postcode],
        v.[first_name], v.[last_name], v.[client_specific_id], v.[name], v.phone,
        v.Location_id, v.Contact_id, v.Event_ID, v.client_id, v.program_id,
        v.source_code_id, v.file_source_code_id, v.URL, v.ScriptFrame,
        v.calldatemark, v.NumCallMark + 1 as Numcallmark,
        v.NumCallMarkDay + 1 as NumCallMarkDay,
        v.NumCallMarkWeek + 1 as NumCallMarkWeek, v.autoaudio,
        v.autohumantext, v.automachinetext 
   FROM vw_locationcontactdialer v 
  WHERE v.program_id = 10001565
    and v.numcallmark < 3 
    and (dateadd(hh,72,v.calldatemark) < getdate()
        or v.calldatemark = '01/01/1900' or v.calldatemark is null) 
    and  source_code_id = 10015311 
    and v.contact_id not in ( select contact_ID from CALL_HISTORY with (NOLOCK) 
                               where program_ID = 10001565 
                                 and result_id not in ('8','U','N')
                               group by contact_ID)
  order by calldatemark

JOIN を試してみるようにというヒントが与えられましたが、どうすればこれを達成できるかわかりません。JOIN を実行する方法がわかりません。すべての contact_id がサブクエリに含まれていないことを確認してください。

私はこれを思いついた:

SELECT TOP 1 v.[address], v.[address2], v.[city], v.[state_prov_id],v.[postcode],
            v.[first_name], v.[last_name], v.[client_specific_id], v.[name],
            v.phone, v.Location_id, v.Contact_id, v.Event_ID, v.client_id,
            v.program_id, v.source_code_id, v.file_source_code_id, v.URL,
            v.ScriptFrame, v.calldatemark,
            v.NumCallMark + 1 as Numcallmark,
            v.NumCallMarkDay + 1 as NumCallMarkDay,
            v.NumCallMarkWeek + 1 as NumCallMarkWeek, v.autoaudio,
            v.autohumantext, v.automachinetext 
  from vw_locationcontactdialer v 
  JOIN CALL_HISTORY ch on v.Contact_ID = ch.contact_ID
 where v.Program_ID = 10001565
   and v.NumCallMark < 3
   and (DATEADD(hh,72,v.calldatemark) < GETDATE() 
        or v.CallDateMark = '01/01/1900' or v.CallDateMark is null)
   and v.Source_Code_ID = 10015311
   and ch.result_ID not in ('8','U','N')
 group by ch.contact_id
 order by v.CallDateMark

しかし、私が完全に理解していないこのエラーのために機能していません: Msg 8120, Level 16, State 1, Line 1 Column 'vw_locationcontactdialer.address' is invalid in the select list because it is not included in a aggregate functionまたは GROUP BY 句。

どんな助けでも素晴らしいでしょう。

4

3 に答える 3

1

ちょっとしたヒントを1つ挙げます。「(DATEADD(hh、72、v.calldatemark)<GETDATE()」という句は、calldatemarkフィールドのインデックスが使用されないようにします。「v.calldatemark<」に置き換えると役立つ場合があります。 DATEADD(hh、-72、GETDATE())"。

また、「groupby」は無視してください。特定のcontact_Idsにのみ関心があります。副選択の結果に含まれるエントリが少ない場合、これをJOINに変換するときにパフォーマンスは得られません。

コメントですでに述べているように、パフォーマンスの低下の根本的な原因である可能性があるため、基になるビューのスキーマを調べて、最終的に投稿する必要があります。

于 2012-11-12T21:53:09.190 に答える
1

次のように、これを結合に変えることができます。

from vw_locationcontactdialer v left outer join
     (select contact_ID
      from CALL_HISTORY with (NOLOCK) 
      where program_ID = 10001565 and 
            result_id not in ('8','U','N')
      group by contact_ID
     ) ch
     on v.contact_id = vh.contact_id
where . . .
      ch.contact_id is null
order by calldatemark

(申し訳ありませんが、クエリ全体を投稿しようとするとエラーが発生します。)

ただし、これをよりうまく機能させるには、元のクエリに戻って相関サブクエリを使用することをお勧めします。

where
      not exists (select 1
                  from CALL_HISTORY ch with (NOLOCK) 
                  where program_ID = 10001565 and 
                        result_id not in ('8','U','N') and
                        ch.contact_id = v.contact_id
                 )

CALL_HISTORY.Contact_Id にインデックスがあれば役に立ちます。さらに優れているのは、contact_id、result_id、および program_id を含む Call_History のマルチパート インデックスです。

于 2012-11-12T21:54:48.573 に答える
0

これを正しく機能させる方法を見つけました。これが私のコードです。

Select top 1 v.[address], v.[address2], v.[city], v.[state_prov_id], v.[postcode], 
v.[first_name], v.[last_name], v.[client_specific_id], v.[name], 
v.phone, v.Location_id, v.Contact_id, v.Event_ID, v.client_id, v.program_id,
v.source_code_id, v.file_source_code_id, v.URL, v.ScriptFrame, v.calldatemark,
v.NumCallMark + 1 as Numcallmark, 
v.NumCallMarkDay + 1 as NumCallMarkDay, 
v.NumCallMarkWeek + 1 as NumCallMarkWeek, v.autoaudio, 
v.autohumantext, v.automachinetext 
from vw_locationcontactdialer v 
left join (select contact_id from CALL_HISTORY 
where program_ID = 10001565 and result_ID not in ('8','U','N') 
group by contact_ID) h on v.Contact_ID = h.contact_ID 
where v.program_id = 10001565 
and v.numcallmark < 3 and (dateadd(hh,72,v.calldatemark) < getdate() 
or v.calldatemark = '01/01/1900' or v.calldatemark is null) 
and  source_code_id = 10015311  
and h.contact_ID is null order by calldatemark
于 2012-11-19T15:37:57.293 に答える