Повышение эффективности запросов SQL - пробовали индексирование, курсор и параллелизм - PullRequest
0 голосов
/ 03 августа 2020

этот запрос занимает от 6 1/2 до 8 часов в зависимости от того, использую ли я индексированную таблицу или курсор. Недавно я узнал о параллелизме (OPTION (USE HINT ('ENABLE_PARALLEL_PLAN_PREFERENCE'), но это, похоже, не помогает. Это медленнее, чем если бы я не использовал его в первом запросе. Я должен признать, что я не совсем понимаю использование параллелизма.

Проблема, с которой я сталкиваюсь, заключается в том, что я внутренне присоединяюсь к одной большой таблице (SS_DB.dbo.Path_Statistics_wBatchId), содержащей 11 MM-записей с меньшей таблицей (SS_DB.dbo.sfactors) как две В меньшей таблице содержится 250 000 записей. Таким образом, запрос, возможно, выполняется для 3 триллионов записей (11 M x 250 K). Мне удалось выполнить запрос, и в итоговой базе данных (SS_DB.dbo.Path0_test) было 550 M записей.

Не могли бы вы предложить какие-либо предложения по повышению производительности любого из двух запросов ниже или любого другого подхода, пожалуйста?

Это два подхода, которые я пробовал: один без курсора и без индекса (фактически index вызывает больше проблем) и один с курсором.

       select
              fi.ISO
              ,fi.BatchId
              ,sf_sr.constraint_name
              ,fi.Source as SOURCENAME
              ,fi.Sink as SINKNAME
              ,fi.TOU
              ,fi.Source + '_' + fi.Sink + '_' + fi.TOU as ftr_path
              ,round((a.ACP_$MWH - b.ACP_$MWH),4) LSP
              ,coalesce(sf_sr.SFValue,0) - coalesce(sf_sn.SFValue,0) as pathsf
              , sf_sr.SFValue as sr_sf
              , sf_sn.SFValue as sn_sf
              ,sf_sr.CID
              ,(fi.wrr_rev+fi.wrr_pl+fi.cumlroi) score
              ,maxrevmwh, avgrevmwh, minrevmwh, posovertotalrev, wrr_rev, sumposrev, sumnegrev, totalrev, wrr_pl, sumwin, sumloss, cumlroi, totalpl, totalcost,
              posrevcntpct, negrevcntpct, winpct, losspct, avgpl, avgcost, avgposrev, avgnegrev, rr_pl, maxcostmwh, maxplmwh, avgcostmwh, avgplmwh, mincostmwh,
              minplmwh, trades, stdevpl, stdevWin, stdevLoss, stdevrev, stdevposrev, stdevnegrev, stdevposrevmwh, stdevnegrevmwh, maxdate, mindate, Sortino_rev,
              Sharpe_rev, Sortino_pl, Sharpe_pl, obl0, obl5, obl10, obl15, obl20, obl25, obl30, obl35, obl40, obl45, obl50, obl55, obl60, obl65, obl70, obl75,
              obl80, obl85, obl90, obl95, obl100, opt0, opt5, opt10, opt15, opt20, opt25, opt30, opt35, opt40, opt45, opt50, opt55, opt60, opt65, opt70,
              opt75, opt80, opt85, opt90, opt95, opt100
       INTO SS_DB.dbo.Path0_test
       from  SS_DB.dbo.Path_Statistics_wBatchId fi with(NOLOCK) 
       inner join SS_DB.dbo.sfactors sf_sr on sf_sr.PNode_Name = fi.Source
       inner join SS_DB.dbo.sfactors sf_sn on sf_sn.PNode_Name = fi.Sink
                     and sf_sr.constraint_name = sf_sn.constraint_name
                     and sf_sr.contingency = sf_sn.contingency
                     and sf_sr.SFDate = sf_sn.SFDate
                     and sf_sr.CID = sf_sn.CID
                     and abs(sf_sr.SFValue - sf_sn.SFValue)>=0.001          
       inner join SS_DB.dbo.LSP a on fi.Source = a.SourceSink and fi.TOU = a.TOU_Mod
       inner join SS_DB.dbo.LSP b on fi.Sink = b.SourceSink and fi.TOU = b.TOU_Mod
       and fi.ISO= 'MISO'
       --where fi.BatchId <50
       OPTION(USE HINT('ENABLE_PARALLEL_PLAN_PREFERENCE'));

Этот запрос использует курсоры:

DECLARE @ig as cursor;
DECLARE @batch as int = 1;

set @ig = cursor for 
select distinct fi.BatchId from SS_DB.dbo.Path_Statistics_wBatchId fi --where fi.BatchId < 100;

open @ig;

fetch next from @ig into @batch;

while @@FETCH_STATUS = 0


begin
    PRINT @batch;
       
INSERT INTO SS_DB.dbo.Path0
       select
              fi.ISO
              ,fi.BatchId
              ,sf_sr.constraint_name
              ,fi.Source as SOURCENAME
              ,fi.Sink as SINKNAME
              ,fi.TOU
              ,fi.Source + '_' + fi.Sink + '_' + fi.TOU as ftr_path
              ,round((a.ACP_$MWH - b.ACP_$MWH),4) LSP
              ,coalesce(sf_sr.SFValue,0) - coalesce(sf_sn.SFValue,0) as pathsf
              , sf_sr.SFValue as sr_sf
              , sf_sn.SFValue as sn_sf
              ,sf_sr.CID
              ,(fi.wrr_rev+fi.wrr_pl+fi.cumlroi) score
              ,maxrevmwh, avgrevmwh, minrevmwh, posovertotalrev, wrr_rev, sumposrev, sumnegrev, totalrev, wrr_pl, sumwin, sumloss, cumlroi, totalpl, totalcost,
              posrevcntpct, negrevcntpct, winpct, losspct, avgpl, avgcost, avgposrev, avgnegrev, rr_pl, maxcostmwh, maxplmwh, avgcostmwh, avgplmwh, mincostmwh,
              minplmwh, trades, stdevpl, stdevWin, stdevLoss, stdevrev, stdevposrev, stdevnegrev, stdevposrevmwh, stdevnegrevmwh, maxdate, mindate, Sortino_rev,
              Sharpe_rev, Sortino_pl, Sharpe_pl, obl0, obl5, obl10, obl15, obl20, obl25, obl30, obl35, obl40, obl45, obl50, obl55, obl60, obl65, obl70, obl75,
              obl80, obl85, obl90, obl95, obl100, opt0, opt5, opt10, opt15, opt20, opt25, opt30, opt35, opt40, opt45, opt50, opt55, opt60, opt65, opt70,
              opt75, opt80, opt85, opt90, opt95, opt100
       from  SS_DB.dbo.Path_Statistics_wBatchId fi with(NOLOCK) 
       inner join SS_DB.dbo.sfactors sf_sr on sf_sr.PNode_Name = fi.Source
       inner join SS_DB.dbo.sfactors sf_sn on sf_sn.PNode_Name = fi.Sink
                     and sf_sr.constraint_name = sf_sn.constraint_name
                     and sf_sr.contingency = sf_sn.contingency
                     and sf_sr.SFDate = sf_sn.SFDate
                     and sf_sr.CID = sf_sn.CID
                     and abs(sf_sr.SFValue - sf_sn.SFValue)>=0.001          
       inner join SS_DB.dbo.LSP a on fi.Source = a.SourceSink and fi.TOU = a.TOU_Mod
       inner join SS_DB.dbo.LSP b on fi.Sink = b.SourceSink and fi.TOU = b.TOU_Mod
       and fi.ISO= 'MISO'
       where fi.BatchId = @batch

fetch next from @ig into @batch;
end

close @ig;
deallocate @ig;
...