0

誰かが私に違いを教えてください...私は何が問題なのかわからず、それをstackoverflowで検索するためにいくつかの単語でそれを説明する方法がわかりません,) .........

SQL Server 2008 R2 x64 でのこの選択には、約 1 分 16 秒かかります

select T_MESSAGE.MSG_GUID from T_MESSAGE
where 
T_MESSAGE.MSG_BODY like @searchpattern
or T_MESSAGE.MSG_COMMENT like @searchpattern
or T_MESSAGE.MSG_SEDERDISPLAYINFORMATION like @searchpattern 
or (select COUNT(*) from T_RECIPIENT 
          join T_RECIPIENT_ANDROID on T_RECIPIENT_ANDROID.RAND_REC_GUID = T_RECIPIENT.REC_GUID 
    where T_RECIPIENT.REC_MSG_GUID = T_MESSAGE.MSG_GUID 
    and T_RECIPIENT_ANDROID.RAND_DEVICETOKEN like @searchpattern) > 0   
or (select COUNT(*) from T_RECIPIENT 
    join T_RECIPIENT_IOS on T_RECIPIENT_IOS.RIOS_REC_GUID = T_RECIPIENT.REC_GUID 
    where T_RECIPIENT.REC_MSG_GUID = T_MESSAGE.MSG_GUID 
    and T_RECIPIENT_IOS.RIOS_DEVICETOKEN like @searchpattern) > 0
or (select COUNT(*) from T_RECIPIENT 
    join T_RECIPIENT_SMS on T_RECIPIENT_SMS.RSMS_REC_GUID = T_RECIPIENT.REC_GUID 
    where T_RECIPIENT.REC_MSG_GUID = T_MESSAGE.MSG_GUID 
    and T_RECIPIENT_SMS.RSMS_PHONENUMBER like @searchpattern) > 0
or (select COUNT(*) from T_RECIPIENT 
    join T_RECIPIENT_SMTP on T_RECIPIENT_SMTP.RSMTP_REC_GUID = T_RECIPIENT.REC_GUID 
    where T_RECIPIENT.REC_MSG_GUID = T_MESSAGE.MSG_GUID 
    and T_RECIPIENT_SMTP.RSMTP_ADDRESS like @searchpattern) > 0

このコードは数ミリ秒しかかかりません..

select T_MESSAGE.MSG_GUID from T_MESSAGE
where 
T_MESSAGE.MSG_BODY like @searchpattern
or T_MESSAGE.MSG_COMMENT like @searchpattern
or T_MESSAGE.MSG_SEDERDISPLAYINFORMATION like @searchpattern 
or (select COUNT(*) from T_RECIPIENT 
          join T_RECIPIENT_ANDROID on T_RECIPIENT_ANDROID.RAND_REC_GUID = T_RECIPIENT.REC_GUID 
    where T_RECIPIENT.REC_MSG_GUID = T_MESSAGE.MSG_GUID 
    and T_RECIPIENT_ANDROID.RAND_DEVICETOKEN like @searchpattern) > 0   
or (select COUNT(*) from T_RECIPIENT 
    join T_RECIPIENT_IOS on T_RECIPIENT_IOS.RIOS_REC_GUID = T_RECIPIENT.REC_GUID 
    where T_RECIPIENT.REC_MSG_GUID = T_MESSAGE.MSG_GUID 
    and T_RECIPIENT_IOS.RIOS_DEVICETOKEN like @searchpattern) > 0
or (select COUNT(*) from T_RECIPIENT 
    join T_RECIPIENT_SMS on T_RECIPIENT_SMS.RSMS_REC_GUID = T_RECIPIENT.REC_GUID 
    where T_RECIPIENT.REC_MSG_GUID = T_MESSAGE.MSG_GUID 
    and T_RECIPIENT_SMS.RSMS_PHONENUMBER like @searchpattern) > 0

....うん!そうです、「OR ブロック」の 1 つを削除したところですが、どれを削除しても問題ありません

3つ以上ある場合(!)、クエリに非常に長い時間がかかります(ところで、ブロックの結果が0で、結果だけでなくテーブルも空である場合も)

そして今が来る...

これも非常に高速 ( 1 秒未満) で、すべての「OR ブロック」を含めました。

declare @searchpattern as varchar(MAX)
set @searchpattern = 'mysearchstring'

declare @guidTable table
( 
    MSG_GUID UniqueIdentifier
)

insert into @guidTable 
select T_MESSAGE.MSG_GUID from T_MESSAGE
where 
T_MESSAGE.MSG_BODY like @searchpattern
or T_MESSAGE.MSG_COMMENT like @searchpattern
or T_MESSAGE.MSG_SENDERDISPLAYINFORMATION like @searchpattern 
or (select COUNT(*) from T_RECIPIENT 
    join T_RECIPIENT_ANDROID on T_RECIPIENT_ANDROID.RAND_REC_GUID = T_RECIPIENT.REC_GUID 
    where T_RECIPIENT.REC_MSG_GUID = T_MESSAGE.MSG_GUID 
    and T_RECIPIENT_ANDROID.RAND_DEVICETOKEN like @searchpattern) > 0   

insert into @guidTable 
select T_MESSAGE.MSG_GUID from T_MESSAGE 
where
(select COUNT(*) from T_RECIPIENT 
    join T_RECIPIENT_IOS on T_RECIPIENT_IOS.RIOS_REC_GUID = T_RECIPIENT.REC_GUID 
    where T_RECIPIENT.REC_MSG_GUID = T_MESSAGE.MSG_GUID 
    and T_RECIPIENT_IOS.RIOS_DEVICETOKEN like @searchpattern) > 0 

insert into @guidTable 
select T_MESSAGE.MSG_GUID from T_MESSAGE 
where
(select COUNT(*) from T_RECIPIENT 
    join T_RECIPIENT_SMS on T_RECIPIENT_SMS.RSMS_REC_GUID = T_RECIPIENT.REC_GUID 
    where T_RECIPIENT.REC_MSG_GUID = T_MESSAGE.MSG_GUID 
    and T_RECIPIENT_SMS.RSMS_PHONENUMBER like @searchpattern) > 0

insert into @guidTable 
select T_MESSAGE.MSG_GUID from T_MESSAGE 
where 
(select COUNT(*) from T_RECIPIENT 
    join T_RECIPIENT_SMTP on T_RECIPIENT_SMTP.RSMTP_REC_GUID = T_RECIPIENT.REC_GUID 
    where T_RECIPIENT.REC_MSG_GUID = T_MESSAGE.MSG_GUID 
    and T_RECIPIENT_SMTP.RSMTP_ADDRESS like @searchpattern) > 0


select * from @guidTable 

...選択を分割し、クエリごとに結果クエリを新しい宣言されたテーブルに書き込むだけです...

現在、SQLで関数を作成することでこのタスクを解決しましたが、何が問題なのか誰に教えてもらえますか?

(ところで:DBには現在約5000のエントリしかありません)

4

1 に答える 1

1

existsこれは、必要のないカウントを取得するよりも、使用する方が高速になるはずです。

select T_MESSAGE.MSG_GUID from T_MESSAGE 
where  
T_MESSAGE.MSG_BODY like @searchpattern 
or T_MESSAGE.MSG_COMMENT like @searchpattern 
or T_MESSAGE.MSG_SEDERDISPLAYINFORMATION like @searchpattern  
or exists (select 42 from T_RECIPIENT  
          join T_RECIPIENT_ANDROID on T_RECIPIENT_ANDROID.RAND_REC_GUID = T_RECIPIENT.REC_GUID  
    and T_RECIPIENT.REC_MSG_GUID = T_MESSAGE.MSG_GUID  
    and T_RECIPIENT_ANDROID.RAND_DEVICETOKEN like @searchpattern)
or exists (select 42 from T_RECIPIENT  
    join T_RECIPIENT_IOS on T_RECIPIENT_IOS.RIOS_REC_GUID = T_RECIPIENT.REC_GUID  
    and T_RECIPIENT.REC_MSG_GUID = T_MESSAGE.MSG_GUID  
    and T_RECIPIENT_IOS.RIOS_DEVICETOKEN like @searchpattern)
or exists (select 42 from T_RECIPIENT  
    join T_RECIPIENT_SMS on T_RECIPIENT_SMS.RSMS_REC_GUID = T_RECIPIENT.REC_GUID  
    and T_RECIPIENT.REC_MSG_GUID = T_MESSAGE.MSG_GUID  
    and T_RECIPIENT_SMS.RSMS_PHONENUMBER like @searchpattern)
or exists (select 42 from T_RECIPIENT  
    join T_RECIPIENT_SMTP on T_RECIPIENT_SMTP.RSMTP_REC_GUID = T_RECIPIENT.REC_GUID  
    and T_RECIPIENT.REC_MSG_GUID = T_MESSAGE.MSG_GUID  
    and T_RECIPIENT_SMTP.RSMTP_ADDRESS like @searchpattern)

また、結合が適切なインデックスでサポートされていることも確認する必要があります。

于 2012-07-04T16:49:34.027 に答える