SQL Server 2016には次のクエリがあります。「ここにコードを入力」列のコードがないため、SUBSTRING
で検索する必要がありました。しかし、予想どおり遅いため、クエリは00:03:37
で終了します。
with cte as
(
-- De Incidente para Requisição
select
cdchamado AS [Chamado]
,'De Incidente para Requisição' AS [Tipo de Alteração]
,dtacompanhamento AS [Alterado Em]
from
[dbo].[hd_acompanhamento]
where
SUBSTRING(dsacompanhamento,45,36) = 'incidente para requisição de serviço'
union
-- De Requisição para Incidente
select
cdchamado AS [Chamado]
,'De Requisição para Incidente' AS [Tipo de Alteração]
,dtacompanhamento AS [Alterado Em]
from
[dbo].[hd_acompanhamento]
where
SUBSTRING(dsacompanhamento,45,36) = 'requisição de serviço para incidente'
)
select * from cte
一時テーブルを作成し、必要なデータのみを挿入することを考えたので、このテーブルはSQL Serverエージェントのジョブによって更新されます。しかし、それが最善の解決策であるかどうかはわかりません。
IMO、計算列の主要な候補ではありませんが、UIまたはジョブを介してテーブルがどのように入力されるかを知ることが重要です。
もう1つのポイントは、述語がハードコーディングされている理由です。頻繁に変更できますか?
もう1つのポイントは、@ ErikがUNION
をポイントし、UNION
を削除するとクエリが向上することです。
with cte as
(
-- De Incidente para Requisição
select
cdchamado AS [Chamado]
,'De Incidente para Requisição' AS [Tipo de Alteração]
,dtacompanhamento AS [Alterado Em]
from
[dbo].[hd_acompanhamento]
where
SUBSTRING(dsacompanhamento,45,36) = 'incidente para requisição de serviço'
)
-- De Requisição para Incidente
select
cdchamado AS [Chamado]
,'De Requisição para Incidente' AS [Tipo de Alteração]
,dtacompanhamento AS [Alterado Em]
from
[dbo].[hd_acompanhamento]
where
SUBSTRING(dsacompanhamento,45,36) = 'requisição de serviço para incidente'
and not exists(select 1 from CTE 1 where hd_acompanhamento].somekeyCol = c.somekeyCol)
union all
select * from cte
このために2つの計算列を作成できます。
ALTER TABLE [dbo].[hd_acompanhamento]
ADD IsServiceRequest AS
CASE WHEN SUBSTRING(dsacompanhamento,45,36) = 'requisição de serviço para incidente' THEN 1
ELSE 0 END;
ALTER TABLE [dbo].[hd_acompanhamento]
ADD IsIncident AS
CASE WHEN SUBSTRING(dsacompanhamento,45,36) = 'incidente para requisição de serviço' THEN 1
ELSE 0 END;
そしてそれらにインデックスを付けます:
CREATE INDEX IX_IsServiceRequest
ON [dbo].[hd_acompanhamento] (IsServiceRequest);
CREATE INDEX IX_IsIncident
ON [dbo].[hd_acompanhamento] (IsIncident);
次に、クエリを次のように書き換えることができます。
with cte as
(
-- De Incidente para Requisição
select
cdchamado AS [Chamado]
,'De Incidente para Requisição' AS [Tipo de Alteração]
,dtacompanhamento AS [Alterado Em]
from
[dbo].[hd_acompanhamento]
where
IsIncident = 1
union
-- De Requisição para Incidente
select
cdchamado AS [Chamado]
,'De Requisição para Incidente' AS [Tipo de Alteração]
,dtacompanhamento AS [Alterado Em]
from
[dbo].[hd_acompanhamento]
where
IsServiceRequest = 1
)
select * from cte
これにより、サブストリング関数を実行しているテーブル全体をスキャンするのではなく、特定の行に対してクエリseekを実行できます。
キーのルックアップを回避するために、cdchamado
およびdtacompanhamento
列をインデックスに含まれる列として追加することもできます。それらのデータ型がわからないため、デフォルトでは含めませんでした。それらが大きなテキスト値である場合は、キールックアップのままにしておく方がよい場合があります。
別のオプションとして、1つの計算された列/インデックスのオーバーヘッドのみが必要な場合は、次のように組み合わせることができます。
ALTER TABLE [dbo].[hd_acompanhamento]
ADD ServiceRequestType AS
CASE
WHEN SUBSTRING(dsacompanhamento,45,36) = 'requisição de serviço para incidente' THEN 1
WHEN SUBSTRING(dsacompanhamento,45,36) = 'incidente para requisição de serviço' THEN 2
ELSE 0
END;
次に、その1つの列だけにインデックスを付けて、ServiceType = 1
およびServiceType = 2
は、2つのクエリを一緒に結合します。 Erik Darling へのハットヒント。