0

私はあなたがこれで私を助けてくれることを本当に望んでいます。これは私の現在のコードであり、これまでのところ、私が作成できる最高のコードです。

 SELECT
      max(t2.pmskey) as pmskey, max(cast(t1.recdate as datetime)) as recdate,
      max(t2.mrtype) as mrtype, max(cast(t1.mrdate as datetime)) as mrdate,
      max(t2.CaseNo) as CaseNo, max(t2.pmclin) as pmclin,
      max(cast(t1.nexteval as datetime)) as nexteval,
      max(cast(t1.repdate as datetime)) as repdate,
      max(t3.mrprocedure) as mrprocedure, max(t2.med_stat) as med_stat,
      max(cast(t1.med_stateff as datetime)) as med_stateff,
      max(t2.clincontact) as clincontact,
      max(cast(t1.datemodf as datetime)) as datemodf, max(t2.modfby) as modfby,
      max(cast(t1.inceptiondate as datetime)) as inceptiondate,
      max(t2.createdby) as createdby, max(cast(t1.date_ent as datetime)) as date_ent,
      max(t2.ppihandler) as ppihandler

 FROM
      tblpms as t1

 JOIN
      (
      select * from tblpms where lower(CaseNo) like '%tr13-011%'

 AND
      cast(mrdate as datetime) IN (select max(cast(mrdate as datetime))
      from tblpms where lower(CaseNo) like '%tr13-011%')
      ) as t2

      on t1.CaseNo COLLATE DATABASE_DEFAULT = t2.CaseNo COLLATE DATABASE_DEFAULT

 JOIN
      (
      select * from tblpms where lower(CaseNo) like '%tr13-011%'

 AND
      lower(mrprocedure) is not null and cast(nexteval as datetime)
      in (select max(cast(nexteval as datetime)) from
      tblpms where lower(CaseNo) like '%tr13-011%')
      ) as t3

      on t1.CaseNo COLLATE DATABASE_DEFAULT = t2.CaseNo COLLATE DATABASE_DEFAULT

      and lower(t2.CaseNo) like '%tr13-011%'

の基準lower(CaseNo)はすべての結合で複製されており、それらを減らす方法がわかりません。何かできることがあると思います。そして、他に最適化できるものがあれば、それを答えに含めてください。

これは、以下の回答に基づく私の現在のクエリです。

 SELECT
      max(t2.pmskey) as pmskey, max(cast(t1.recdate as datetime)) as recdate,
      max(t2.mrtype) as mrtype, max(cast(t1.mrdate as datetime)) as mrdate,
      max(t2.CaseNo) as CaseNo, max(t2.pmclin) as pmclin,
      max(cast(t1.nexteval as datetime)) as nexteval,
      max(cast(t1.repdate as datetime)) as repdate,
      max(t3.mrprocedure) as mrprocedure, max(t2.med_stat) as med_stat,
      max(cast(t1.med_stateff as datetime)) as med_stateff,
      max(t2.clincontact) as clincontact,
      max(cast(t1.datemodf as datetime)) as datemodf, max(t2.modfby) as modfby,
      max(cast(t1.inceptiondate as datetime)) as inceptiondate,
      max(t2.createdby) as createdby, max(cast(t1.date_ent as datetime)) as date_ent,
      max(t2.ppihandler) as ppihandler

 FROM
      tblpms as t1

 JOIN
      (
      select * from tblpms where CaseNo = 'TR13-011-CRW'

 AND
      cast(mrdate as datetime) IN (select max(cast(mrdate as datetime))
      from tblpms where CaseNo = 'TR13-011-CRW')
      ) as t2

      on t1.CaseNo COLLATE DATABASE_DEFAULT = t2.CaseNo COLLATE DATABASE_DEFAULT

 JOIN
      (
      select * from tblpms where CaseNo = 'TR13-011-CRW'

 AND
      lower(mrprocedure) is not null and cast(nexteval as datetime)
      in (select max(cast(nexteval as datetime)) from
      tblpms where CaseNo = 'TR13-011-CRW')
      ) as t3

      on t1.CaseNo COLLATE DATABASE_DEFAULT = t2.CaseNo COLLATE DATABASE_DEFAULT

      and CaseNo = 'TR13-011-CRW'
4

1 に答える 1

3

デフォルトでは大文字と小文字が区別されないため、通常lower()、と照合する場合は必要ありません。LIKE

また、文字列の途中(例LIKE '%whatever%)で検索を行った場合、インデックスは使用されません。ちなみに、インデックスはありますか?クエリプランを作成しようとしましたか?

私が見ることができるように、この問題に対するいくつかの可能な解決策があります:

  1. 全文検索を使用する
  2. 別のインデックス付きフィールドを追加し、クエリの前に1回入力します。

    update tblpms set tr13_flag=1 where CaseNo like '%tr13-011%'

    where lower(CaseNo) like '%tr13-011%'次に、すべてのステートメントを次のように置き換えますwhere tr13_flag=1

  3. 上記の差異:インデックス付きのPERSISTED計算列を使用するため、フラグを手動で計算する必要がありません。

  4. すべての貴重な行を一時テーブルに一度取得します。

    select * into#tr13011 from tblpms where lower(CaseNo)like'%tr13-011%'

それに参加して、おそらく興味深いフィールドにインデックスを追加します。

また、あなたはcast継続的に:cast(nexteval as datetime)。回答から4番目のバージョンを使用#tempし、同時にテーブルにキャストします。

この状態は私には役に立たないように見えます:and lower(mrprocedure) is not null and cast(nexteval as datetime)。なぜ単純ではないのですand mrprocedure is not nullか?

バージョン4の例

select
    CaseNo,
    mrprocedure,
    cast(mrdate as datetime) as mrdate,
    cast(nexteval as datetime) as nexteval
    -- other required fields from tblpms table
into #tr13
from tblpms where CaseNo = 'TR13-011-CRW'

declare @max_mrdate datetime
declare @max_nexteval datetime

select @max_mrdate=max(mrdate), @max_nexteval=max(nexteval) from #tr13

SELECT
      max(t2.pmskey) as pmskey, max(cast(t1.recdate as datetime)) as recdate,
      max(t2.mrtype) as mrtype, max(cast(t1.mrdate as datetime)) as mrdate,
      max(t2.CaseNo) as CaseNo, max(t2.pmclin) as pmclin,
      max(cast(t1.nexteval as datetime)) as nexteval,
      max(cast(t1.repdate as datetime)) as repdate,
      max(t3.mrprocedure) as mrprocedure, max(t2.med_stat) as med_stat,
      max(cast(t1.med_stateff as datetime)) as med_stateff,
      max(t2.clincontact) as clincontact,
      max(cast(t1.datemodf as datetime)) as datemodf, max(t2.modfby) as modfby,
      max(cast(t1.inceptiondate as datetime)) as inceptiondate,
      max(t2.createdby) as createdby, max(cast(t1.date_ent as datetime)) as date_ent,
      max(t2.ppihandler) as ppihandler

 FROM
      tblpms as t1

 JOIN
      (
      select * from #tr13 where mrdate = @max_mrdate
      ) as t2
      on t1.CaseNo COLLATE DATABASE_DEFAULT = t2.CaseNo COLLATE DATABASE_DEFAULT

 JOIN
      (
      select * from #tr13
        where mrprocedure is not null and nexteval = @max_nexteval
      ) as t3
      on t1.CaseNo COLLATE DATABASE_DEFAULT = t2.CaseNo COLLATE DATABASE_DEFAULT

drop table #tr13

COLLATE DATABASE_DEFAULT常に同じテーブルなので、なぜ必要なのかわかりません。ロジックは私にはあまり明確ではありませんが、読みやすく(そしてパフォーマンスが向上する可能性があります)、同じ結果が得られるようです。

select
    CaseNo,
    mrprocedure,
    cast(mrdate as datetime) as mrdate,
    cast(nexteval as datetime) as nexteval,
    pmskey,
    mrtype,
    med_stat,
    clincontact,
    modfby,
    createdby,
    ppihandler
    -- other required fields from tblpms table
into #tr13
from tblpms where CaseNo = 'TR13-011-CRW'

declare @max_mrdate datetime
declare @max_nexteval datetime

select @max_mrdate=max(mrdate), @max_nexteval=max(nexteval) from #tr13

SELECT
      max(t2.pmskey) as pmskey, max(cast(t1.recdate as datetime)) as recdate,
      max(t2.mrtype) as mrtype, max(cast(t1.mrdate as datetime)) as mrdate,
      max(t2.CaseNo) as CaseNo, max(t2.pmclin) as pmclin,
      max(cast(t1.nexteval as datetime)) as nexteval,
      max(cast(t1.repdate as datetime)) as repdate,
      max(t2.mrprocedure) as mrprocedure, max(t2.med_stat) as med_stat,
      max(cast(t1.med_stateff as datetime)) as med_stateff,
      max(t2.clincontact) as clincontact,
      max(cast(t1.datemodf as datetime)) as datemodf, max(t2.modfby) as modfby,
      max(cast(t1.inceptiondate as datetime)) as inceptiondate,
      max(t2.createdby) as createdby, max(cast(t1.date_ent as datetime)) as date_ent,
      max(t2.ppihandler) as ppihandler

 FROM tblpms as t1
 JOIN #tr13 t2 on t1.CaseNo = t2.CaseNo
where
    t2.mrdate = @max_mrdate
    and t2.mrprocedure is not null
    and t2.nexteval = @max_nexteval

drop table #tr13

UPDATE 私たちはそれを次のコードに減らすことができました:

declare @max_mrdate datetime
declare @max_nexteval datetime

select
    @max_mrdate=max(cast(mrdate as datetime)),
    @max_nexteval=max(cast(nexteval as datetime))
from tblpms
where CaseNo = 'TR13-011-CRW'

select *
from tblpms where CaseNo = 'TR13-011-CRW'
and (
    cast(mrdate as datetime) = @max_mrdate
    or
    (mrprocedure is not null and cast(nexteval as datetime) = @max_nexteval)
)
于 2013-03-27T07:18:39.793 に答える