sql server - SQL Query Optimization with Union Select -


i have query, returns 570 rows, runs 2m 35s. in sql query execute, in solution, gives timeout. how can optimize run under 1m, pref 30s.

select  [region] = region.firstname,         [patient] = patient.name,         [patientstatus] = accountrating.name,         [medicalaid] = accounttype.name,         [quoteamount] = (   select top 1 a.response                             dbo.questionnaire q                             join dbo.questionnairedefinition qrd                                 on qrd.questionnairedefinitionid = q.questionnairedefinitionid                                 , qrd.name = 'internal admin'                             left join questiondefinition qd                                 on q.questionnairedefinitionid = qd.questionnairedefinitionid                                 , qd.questiondefinitionid = 5966                             left outer join answer                                 on a.questionnaireid = q.questionnaireid                                 , a.questiondefinitionid = qd.questiondefinitionid                             q.isactive = 1                             , q.subscriberid = 240                             , q.accountid = patient.accountid                         ),         [invoiceamount] =   (   select top 1 a.response                                 dbo.questionnaire q                                 join dbo.questionnairedefinition qrd                                     on qrd.questionnairedefinitionid = q.questionnairedefinitionid                                     , qrd.name = 'internal admin'                                 left join questiondefinition qd                                     on q.questionnairedefinitionid = qd.questionnairedefinitionid                                     , qd.questiondefinitionid = 5969                                 left outer join answer                                     on a.questionnaireid = q.questionnaireid                                     , a.questiondefinitionid = qd.questiondefinitionid                                 q.isactive = 1                                 , q.subscriberid = 240                                 , q.accountid = patient.accountid                             ),         [datesubmitted] =   (   select top 1 a.response                                 dbo.questionnaire q                                 join dbo.questionnairedefinition qrd                                     on qrd.questionnairedefinitionid = q.questionnairedefinitionid                                     , qrd.name = 'internal admin'                                 left join questiondefinition qd                                     on q.questionnairedefinitionid = qd.questionnairedefinitionid                                     , qd.questiondefinitionid = 5965                                 left outer join answer                                     on a.questionnaireid = q.questionnaireid                                     , a.questiondefinitionid = qd.questiondefinitionid                                 q.isactive = 1                                 , q.subscriberid = 240                                 , q.accountid = patient.accountid                             ),         [dateapproveddeclined] =    (   select top 1 a.response                                         dbo.questionnaire q                                         join dbo.questionnairedefinition qrd                                             on qrd.questionnairedefinitionid = q.questionnairedefinitionid                                             , qrd.name = 'internal admin'                                         left join questiondefinition qd                                             on q.questionnairedefinitionid = qd.questionnairedefinitionid                                             , qd.questiondefinitionid = 5968                                         left outer join answer                                             on a.questionnaireid = q.questionnaireid                                             , a.questiondefinitionid = qd.questiondefinitionid                                         q.isactive = 1                                         , q.subscriberid = 240                                         , q.accountid = patient.accountid                                     ),         [intadmformcreateddate]= q.datecreated,         [hasadminform] = 'yes',         [createdbyuser] = patientcreatedby.name dbo.account patient join dbo.accountrating     on patient.accountratingid = accountrating.accountratingid join dbo.accounttype     on patient.accounttypeid = accounttype.accounttypeid join dbo.[user] region     on patient.userid = region.userid join dbo.[user] patientcreatedby     on patient.createdby = patientcreatedby.userid join dbo.questionnaire q     on patient.accountid = q.accountid  patient.subscriberid = 240     , (q.datecreated < dateadd(d, 26, dateadd(month, datediff(month, convert(datetime, '1900-01-01 00:00:00', 102), getdate()), convert(datetime, '1900-01-01 00:00:00', 102))))     , q.questionnairedefinitionid = 235     , q.isactive = 1     , region.firstname <> 'rubbish'  union select    [region] = region.firstname,                  [patient] = patient.name,                  [patientstatus] = accountrating.name,                  [medicalaid] = accounttype.name,                  [quoteamount] = '0',                  [invoiceamount] = '0',                  [datesubmitted] = '',                  [dateapproveddeclined] = '',                 [intadmformcreateddate] = '',                 [hasadminform] = 'no',                 [createdbyuser] = patientcreatedby.name  dbo.account patient  join dbo.accountrating     on patient.accountratingid = accountrating.accountratingid  join dbo.accounttype     on patient.accounttypeid = accounttype.accounttypeid  join dbo.[user] region     on patient.userid = region.userid  join dbo.[user] patientcreatedby     on patient.createdby = patientcreatedby.userid not exists(   select *                      questionnaire q                      patient.accountid = q.accountid                      , q.questionnairedefinitionid = 235                     , patient.subscriberid = 240                     , q.subscriberid = 240                 )     , patient.subscriberid = 240     , patient.datecreated < dateadd(d, 26, dateadd(month, datediff(month, convert(datetime, '1900-01-01 00:00:00', 102), getdate()), convert(datetime, '1900-01-01 00:00:00', 102)))     , region.firstname <> 'rubbish' 

here version of query tried, runs same time.

select  [region] = region.firstname,         [patient] = patient.name,         [patientstatus] = accountrating.name,         [medicalaid] = accounttype.name,         [quoteamount] = q1.response,         [invoiceamount] = q2.response,         [datesubmitted] = q3.response,         [dateapproveddeclined] = q4.response,         [intadmformcreateddate]= q.datecreated,         [hasadminform] = 'yes',         [createdbyuser] = patientcreatedby.name dbo.account patient join dbo.accountrating     on patient.accountratingid = accountrating.accountratingid join dbo.accounttype     on patient.accounttypeid = accounttype.accounttypeid join dbo.[user] region     on patient.userid = region.userid join dbo.[user] patientcreatedby     on patient.createdby = patientcreatedby.userid join dbo.questionnaire q     on patient.accountid = q.accountid outer apply (     select top 1    q.accountid,             a.response     dbo.questionnaire q     join dbo.questionnairedefinition qrd         on qrd.questionnairedefinitionid = q.questionnairedefinitionid         , qrd.name = 'internal admin'     left join questiondefinition qd         on q.questionnairedefinitionid = qd.questionnairedefinitionid         , qd.questiondefinitionid = 5966     left outer join answer         on a.questionnaireid = q.questionnaireid         , a.questiondefinitionid = qd.questiondefinitionid     q.isactive = 1     q.subscriberid = 240     , q.accountid = patient.accountid ) q1 outer apply (     select top 1    q.accountid,                     a.response     dbo.questionnaire q     join dbo.questionnairedefinition qrd         on qrd.questionnairedefinitionid = q.questionnairedefinitionid         , qrd.name = 'internal admin'     left join questiondefinition qd         on q.questionnairedefinitionid = qd.questionnairedefinitionid         , qd.questiondefinitionid = 5969     left outer join answer         on a.questionnaireid = q.questionnaireid         , a.questiondefinitionid = qd.questiondefinitionid     q.isactive = 1     , q.accountid = patient.accountid ) q2 outer apply (     select top 1    q.accountid,             a.response     dbo.questionnaire q     join dbo.questionnairedefinition qrd         on qrd.questionnairedefinitionid = q.questionnairedefinitionid         , qrd.name = 'internal admin'     left join questiondefinition qd         on q.questionnairedefinitionid = qd.questionnairedefinitionid         , qd.questiondefinitionid = 5965     left outer join answer         on a.questionnaireid = q.questionnaireid         , a.questiondefinitionid = qd.questiondefinitionid     q.isactive = 1     , q.accountid = patient.accountid ) q3 outer apply (     select top 1    q.accountid,                     a.response     dbo.questionnaire q     join dbo.questionnairedefinition qrd         on qrd.questionnairedefinitionid = q.questionnairedefinitionid         , qrd.name = 'internal admin'     left join questiondefinition qd         on q.questionnairedefinitionid = qd.questionnairedefinitionid         , qd.questiondefinitionid = 5968     left outer join answer         on a.questionnaireid = q.questionnaireid         , a.questiondefinitionid = qd.questiondefinitionid     q.isactive = 1     , q.accountid = patient.accountid ) q4 patient.subscriberid = 240     , (q.datecreated < dateadd(d, 26, dateadd(month, datediff(month, convert(datetime, '1900-01-01 00:00:00', 102), getdate()), convert(datetime, '1900-01-01 00:00:00', 102))))     , q.questionnairedefinitionid = 235     , q.isactive = 1     , region.firstname <> 'rubbish'  union select    [region] = region.firstname,                  [patient] = patient.name,                  [patientstatus] = accountrating.name,                  [medicalaid] = accounttype.name,                  [quoteamount] = '0',                  [invoiceamount] = '0',                  [datesubmitted] = '',                  [dateapproveddeclined] = '',                 [intadmformcreateddate] = '',                 [hasadminform] = 'no',                 [createdbyuser] = patientcreatedby.name  dbo.account patient  join dbo.accountrating     on patient.accountratingid = accountrating.accountratingid  join dbo.accounttype     on patient.accounttypeid = accounttype.accounttypeid  join dbo.[user] region     on patient.userid = region.userid  join dbo.[user] patientcreatedby     on patient.createdby = patientcreatedby.userid not exists(   select *                      questionnaire q                      patient.accountid = q.accountid                      , q.questionnairedefinitionid = 235                     , patient.subscriberid = 240                     , q.subscriberid = 240                 )     , patient.subscriberid = 240     , patient.datecreated < dateadd(d, 26, dateadd(month, datediff(month, convert(datetime, '1900-01-01 00:00:00', 102), getdate()), convert(datetime, '1900-01-01 00:00:00', 102)))     , region.firstname <> 'rubbish' 

your scalar subqueries share same joins, qd.questiondefinitionid differs.

you can rewrite 4 tops single derived table , join instead:

... left join  (    select         q.accountid,        max(case when qd.questiondefinitionid = 5966 a.response end) [datesubmitted]        max(case when qd.questiondefinitionid = 5968 a.response end) [dateapproveddeclined]        ...    dbo.questionnaire q    join dbo.questionnairedefinition qrd        on qrd.questionnairedefinitionid = q.questionnairedefinitionid        , qrd.name = 'internal admin'    left join questiondefinition qd        on q.questionnairedefinitionid = qd.questionnairedefinitionid    left outer join answer        on a.questionnaireid = q.questionnaireid        , a.questiondefinitionid = qd.questiondefinitionid    q.isactive = 1    , q.subscriberid = 240    group q.accountid  ) q  on q.accountid = patient.accountid 

i used max because didn't have order in subqueries, exact value either doesn't matter or there's single row per value.


Comments

Popular posts from this blog

c++ - llvm function pass ReplaceInstWithInst malloc -

Cross-Compiling Linux Kernel for Raspberry Pi - ${CCPREFIX}gcc -v does not work -

java.lang.NoClassDefFoundError When Creating New Android Project -