简体   繁体   English

从Excel通过ADO到SQL Server 2008的更快查询

[英]Quicker Query from Excel thru ADO to SQL Server 2008

I've developed something to help some of the supervisors in our call center pull their own reports. 我已经开发出一些方法来帮助我们呼叫中心中的某些主管提取他们自己的报告。 This code pulls the data, places it into an Excel table and then that table is used to do calculations on the sheet that they can actually see. 此代码提取数据,将其放入Excel表中,然后使用该表在实际可以看到的工作表上进行计算。 However, when I added the subquery with the openquery statements, it slowed down from taking a few seconds to taking a few minutes in SSMS as well as in Excel. 但是,当我在子查询中添加openquery语句时,它在SSMS和Excel中从几秒钟的速度减慢到几分钟。 Does connecting to a linked server with an openquery statement really slow it down that much? 使用openquery语句连接到链接服务器是否真的会使它减慢这么多? Or is there something in my query slowing it down? 还是我的查询中有一些东西使其速度变慢?

Note: I currently don't have permission to view the execution plan, so I can't see exactly what is slowing it down. 注意:我目前没有查看执行计划的权限,所以我看不到到底是什么在减慢执行速度。

Thanks in advance! 提前致谢!

Dim objConn As New ADODB.Connection
Dim objRecordset As New ADODB.Recordset
Dim drpPicker As DropDown
Dim strDropVal As String
Dim strSQL As String
Dim tblData As ListObject

Set tblData = ThisWorkbook.Sheets("Data").ListObjects("cs")
tblData.DataBodyRange.Rows.Delete

Set drpPicker = ThisWorkbook.Sheets("Dashboard").DropDowns("dropFis_Month")
strDropVal = Format(drpPicker.List(drpPicker.ListIndex), "mmm-yyyy")

strSQL = "" & vbNewLine
strSQL = strSQL + "select" & vbNewLine
strSQL = strSQL + "    case" & vbNewLine
strSQL = strSQL + "        when emp.intCallCenterID=10 then 'Dallas'" & vbNewLine
strSQL = strSQL + "        when emp.intCallCenterID=1 then 'Tracy'" & vbNewLine
strSQL = strSQL + "        when emp.intCallCenterID=2 then 'Ohio'" & vbNewLine
strSQL = strSQL + "    end as 'Call Center'," & vbNewLine
strSQL = strSQL + "    sup.strCsrFirstName+' '+sup.strCsrLastName as 'Supervisor'," & vbNewLine
strSQL = strSQL + "    emp.intempid as 'ID'," & vbNewLine
strSQL = strSQL + "    emp.strCsrFirstName+' '+emp.strCsrLastName as 'Name'," & vbNewLine
strSQL = strSQL + "    fis.ISODate as 'Date'," & vbNewLine
strSQL = strSQL + "    calls as 'Calls'," & vbNewLine
strSQL = strSQL + "    held_calls as 'Held Calls'," & vbNewLine
strSQL = strSQL + "    handle_time as 'Handle Time'," & vbNewLine
strSQL = strSQL + "    talk_time as 'Talk Time'," & vbNewLine
strSQL = strSQL + "    acw_time as 'ACW Time'," & vbNewLine
strSQL = strSQL + "    hold_time as 'Hold Time'," & vbNewLine
strSQL = strSQL + "    ring_time as 'Ring Time'," & vbNewLine
strSQL = strSQL + "    aux_time as 'AUX Time'," & vbNewLine
strSQL = strSQL + "    rona as 'RONA'," & vbNewLine
strSQL = strSQL + "    aux.personaltime/86400 as 'AUX-Personal'," & vbNewLine
strSQL = strSQL + "    COUNT(rls.avayadate) as 'Released Calls'," & vbNewLine
strSQL = strSQL + "    isnull(sched.sched_time,0) as 'Scheduled Time'," & vbNewLine
strSQL = strSQL + "    isnull(xep.sched_xptn,0) as 'Exceptions'," & vbNewLine
strSQL = strSQL + "    isnull(qa.qa_earned,0) as 'QA Points Earned'," & vbNewLine
strSQL = strSQL + "    isnull(qa.qa_possible,0) as 'QA Points Possible'" & vbNewLine
strSQL = strSQL + "from" & vbNewLine
strSQL = strSQL + "    (" & vbNewLine
strSQL = strSQL + "    select" & vbNewLine
strSQL = strSQL + "        sum(CallsHandled) as 'calls'," & vbNewLine
strSQL = strSQL + "        SUM(heldcalls) as 'held_calls'," & vbNewLine
strSQL = strSQL + "        sum(acdtime+acwtime+holdtime) as 'handle_time'," & vbNewLine
strSQL = strSQL + "        sum(ACDTime) as 'talk_time'," & vbNewLine
strSQL = strSQL + "        sum(ACWTime) as 'acw_time'," & vbNewLine
strSQL = strSQL + "        sum(HoldTime) as 'hold_time'," & vbNewLine
strSQL = strSQL + "        sum(ringtime) as 'ring_time'," & vbNewLine
strSQL = strSQL + "        sum(auxtime) as 'aux_time'," & vbNewLine
strSQL = strSQL + "        sum(redirectnoans) as 'rona'," & vbNewLine
strSQL = strSQL + "        employee_id," & vbNewLine
strSQL = strSQL + "        AvayaDate" & vbNewLine
strSQL = strSQL + "    from" & vbNewLine
strSQL = strSQL + "        reporting.dbo.phones" & vbNewLine
strSQL = strSQL + "    Group by" & vbNewLine
strSQL = strSQL + "        employee_id," & vbNewLine
strSQL = strSQL + "        AvayaDate" & vbNewLine
strSQL = strSQL + "    ) fone" & vbNewLine
strSQL = strSQL + "    join ccat.dbo.tblEmployees emp on emp.intEmpID=fone.employee_id" & vbNewLine
strSQL = strSQL + "    join ccat.dbo.tblEmployees sup on sup.id=emp.intSupervisorID" & vbNewLine
strSQL = strSQL + "    join FiscalCal fis on Fis.isodate=fone.AvayaDate" & vbNewLine
strSQL = strSQL + "    left join phones_auxes aux on aux.employee_id=emp.intEmpID and aux.AvayaDate=fis.ISODate" & vbNewLine
strSQL = strSQL + "    left outer join reporting.dbo.agent_releases rls on rls.avayadate=Fis.ISODate and rls.employee_id=emp.intEmpID" & vbNewLine
strSQL = strSQL + "    left outer join (" & vbNewLine
strSQL = strSQL + "    select" & vbNewLine
strSQL = strSQL + "        s.id as 'sched_id'," & vbNewLine
strSQL = strSQL + "        s.employee_id as 'sched_emp'," & vbNewLine
strSQL = strSQL + "        s.schedule_date as 'sched_date'," & vbNewLine
strSQL = strSQL + "        DATEDIFF(ss,s.start_time,s.end_time) as 'sched_time'" & vbNewLine
strSQL = strSQL + "    from" & vbNewLine
strSQL = strSQL + "        reporting.dbo.Schedules s" & vbNewLine
strSQL = strSQL + "    Group by" & vbNewLine
strSQL = strSQL + "        s.schedule_date," & vbNewLine
strSQL = strSQL + "        s.employee_id," & vbNewLine
strSQL = strSQL + "        s.start_time," & vbNewLine
strSQL = strSQL + "        s.end_time," & vbNewLine
strSQL = strSQL + "        s.ID" & vbNewLine
strSQL = strSQL + "    ) sched on sched.sched_date=fis.ISODate and sched.sched_emp=fone.employee_id" & vbNewLine
strSQL = strSQL + "    left outer join (" & vbNewLine
strSQL = strSQL + "    select" & vbNewLine
strSQL = strSQL + "        schedule_id as 'sched_id'," & vbNewLine
strSQL = strSQL + "        SUM(duration)as 'sched_xptn'" & vbNewLine
strSQL = strSQL + "    from" & vbNewLine
strSQL = strSQL + "        reporting.dbo.violations" & vbNewLine
strSQL = strSQL + "    where" & vbNewLine
strSQL = strSQL + "        isapproved = 0" & vbNewLine
strSQL = strSQL + "    Group by" & vbNewLine
strSQL = strSQL + "        schedule_id" & vbNewLine
strSQL = strSQL + "    ) xep on xep.sched_id=sched.sched_id" & vbNewLine
strSQL = strSQL + "    left outer join (" & vbNewLine
strSQL = strSQL + "    select" & vbNewLine
strSQL = strSQL + "        cast(cast(eval.eval_datetime as date) as datetime) as 'qa_date'," & vbNewLine
strSQL = strSQL + "        prsn.personnel_id as 'qa_emp'," & vbNewLine
strSQL = strSQL + "        sum(eval.form_total) as 'qa_earned'," & vbNewLine
strSQL = strSQL + "        sum(eval.form_possible) as 'qa_possible'" & vbNewLine
strSQL = strSQL + "    from" & vbNewLine
strSQL = strSQL + "        openquery ( jeffqms ,'select * from witness.dbo.evaluations' ) eval" & vbNewLine
strSQL = strSQL + "        join openquery ( jeffqms ,'select * from witness.dbo.person' ) prsn ON eval.person_pk = prsn.person_pk" & vbNewLine
strSQL = strSQL + "    where" & vbNewLine
strSQL = strSQL + "        prsn.personnel_id is not null" & vbNewLine
strSQL = strSQL + "        and prsn.login_name is not null" & vbNewLine
strSQL = strSQL + "        and eval.calibration != 'T'" & vbNewLine
strSQL = strSQL + "        and prsn.personnel_id not like 'TestUser'" & vbNewLine
strSQL = strSQL + "        and prsn.personnel_id not like 'IT'" & vbNewLine
strSQL = strSQL + "    Group by" & vbNewLine
strSQL = strSQL + "        personnel_id" & vbNewLine
strSQL = strSQL + "        ,cast(cast(eval.eval_datetime as date) as datetime)) qa on qa.qa_date=fis.ISODate and qa.qa_emp=emp.intEmpID" & vbNewLine
strSQL = strSQL + "where" & vbNewLine
strSQL = strSQL + "    (emp.intCallCenterID=10 or emp.intCallCenterID=1 or emp.intCallCenterID=2)" & vbNewLine
strSQL = strSQL + "    and fis.FIS_MM_YYYY='" & strDropVal & "'" & vbNewLine
strSQL = strSQL + "    and emp.strStatus='active'" & vbNewLine
strSQL = strSQL + "    and (emp.intcscdeptid=14 or emp.intcscdeptid=19) " & vbNewLine
strSQL = strSQL + "Group by" & vbNewLine
strSQL = strSQL + "    Fis.ISODate," & vbNewLine
strSQL = strSQL + "    emp.intEmpID," & vbNewLine
strSQL = strSQL + "    emp.strCsrFirstName," & vbNewLine
strSQL = strSQL + "    emp.strCsrLastName," & vbNewLine
strSQL = strSQL + "    sup.strCsrFirstName," & vbNewLine
strSQL = strSQL + "    sup.strCsrLastName," & vbNewLine
strSQL = strSQL + "    emp.intCallCenterID," & vbNewLine
strSQL = strSQL + "    fone.calls," & vbNewLine
strSQL = strSQL + "    fone.held_calls," & vbNewLine
strSQL = strSQL + "    fone.handle_time," & vbNewLine
strSQL = strSQL + "    fone.talk_time," & vbNewLine
strSQL = strSQL + "    fone.acw_time," & vbNewLine
strSQL = strSQL + "    fone.hold_time," & vbNewLine
strSQL = strSQL + "    fone.ring_time," & vbNewLine
strSQL = strSQL + "    fone.aux_time," & vbNewLine
strSQL = strSQL + "    fone.rona," & vbNewLine
strSQL = strSQL + "    aux.personaltime," & vbNewLine
strSQL = strSQL + "    sched.sched_time," & vbNewLine
strSQL = strSQL + "    xep.sched_xptn," & vbNewLine
strSQL = strSQL + "    qa.qa_earned," & vbNewLine
strSQL = strSQL + "    qa.qa_possible" & vbNewLine
strSQL = strSQL + "Order by" & vbNewLine
strSQL = strSQL + "    [Call Center]," & vbNewLine
strSQL = strSQL + "    Supervisor," & vbNewLine
strSQL = strSQL + "    Name," & vbNewLine
strSQL = strSQL + "    fis.ISODate"

objConn.Open "Provider=SQLOLEDB.1;Initial Catalog=database_name;Data Source=server_name;UID=user_name;PWD=password"

With objRecordset
    .ActiveConnection = objConn
    .Open Source:=strSQL
End With

ThisWorkbook.Sheets("Data").Range("A2").CopyFromRecordset objRecordset

objRecordset.Close
Set objRecordset = Nothing
objConn.Close
Set objConn = Nothing

Do you really need every column (*) from witness.dbo.evaluations? 您真的需要见证人.dbo.evaluations中的每一列(*)吗?

I would add some of the details in your subquery Where clause inside the OpenQuery select statement within the quotes and restrict it to exactly the columns needed. 我会在引号的OpenQuery select语句内的子查询Where子句中添加一些详细信息,并将其限制为所需的确切列。 This will result in more being done at the jeffqms server and less data coming back over the wire. 这将导致在jeffqms服务器上完成更多工作,并减少通过网络返回的数据。

For example in your code above 例如在上面的代码中

select" & vbNewLine
strSQL = strSQL + "        cast(cast(eval.eval_datetime as date) as datetime) as 'qa_date'," & vbNewLine
strSQL = strSQL + "        prsn.personnel_id as 'qa_emp'," & vbNewLine
strSQL = strSQL + "        sum(eval.form_total) as 'qa_earned'," & vbNewLine
strSQL = strSQL + "        sum(eval.form_possible) as 'qa_possible'" & vbNewLine
strSQL = strSQL + "    from" & vbNewLine
strSQL = strSQL + "        openquery ( jeffqms ,'select * from witness.dbo.evaluations' ) eval" & vbNewLine
strSQL = strSQL + "        join openquery ( jeffqms ,'select * from witness.dbo.person' ) prsn ON eval.person_pk = prsn.person_pk" & vbNewLine
strSQL = strSQL + "    where" & vbNewLine
strSQL = strSQL + "        prsn.personnel_id is not null" & vbNewLine
strSQL = strSQL + "        and prsn.login_name is not null" & vbNewLine
strSQL = strSQL + "        and eval.calibration != 'T'" & vbNewLine
strSQL = strSQL + "        and prsn.personnel_id not like 'TestUser'" & vbNewLine
strSQL = strSQL + "        and prsn.personnel_id not like 'IT'" & vbNewLine

"eval.calibration != 'T'", "prsn.personnel_id not like 'TestUser'" and "prsn.personnel_id not like 'IT'" could be put inside the openquery 'select' statement to restrict rows earlier. 可以将“ eval.calibration!='T'”,“ prsn.personnel_id不喜欢'TestUser'”和“ prsn.personnel_id不喜欢'IT'”放置在openquery'select'语句中以限制较早的行。

Also, why not put the entire join between eval and person in one openquery statement to save two trips to jeffqms. 另外,为什么不将eval和person之间的整个联接放在一个openquery语句中,以节省两次jeffqms的旅程。

openquery ( jeffqms ,'select column, column, column from witness.dbo.evaluations join witness.dbo.person where blah blah' )

I always find in the few instances I've had to use openquery, do as much as you can on the remote server first. 我总是发现在少数情况下不得不使用openquery,首先要在远程服务器上做尽可能多的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM