同事說,某某報表查詢很慢,讓我改一下
優化前:
![]()
我這里用的數據庫是:SqlServer
優化前
SELECT COUNT(subquery.JobID) JobNoCount, SISendUser, MAX(SenderName) SendUserName, LocalName, SUM(MasterBillID) MasterBillCopies, SUM(TEU) TEU -- 臨時表:subquery FROM ( SELECT job.jobid ,MAX(bill.SISendTime) SISendTime ,MAX(bill.SISendUser) SISendUser ,MAX(con.FIRST_NAME) SenderName ,MAX(cu.LocalName) LocalName ,count (bill.MasterBillID) MasterBillID -- 這里調用自定義函數查詢 ,COnvert(DECIMAL,dbo.GetContainerTEU(job.jobid)) TEU FROM dbo.oxJob job LEFT JOIN dbo.oxOrder ox ON ox.JobID = job.JobID LEFT JOIN dbo.oxMasterBill bill ON bill.JobID = job.JobID LEFT JOIN dbo.CuCustomer cu ON cu.CustomerID = ox.CarrierCode LEFT JOIN dbo.CONTACT con ON con.CONTACT_GID=bill.SISendUser WHERE CONVERT(char(10),bill.SISendTime,120) BETWEEN '2020-01-01' AND '2020-04-24' GROUP BY job.JobID ) subquery GROUP BY subquery.SISendUser,subquery.LocalName
執行時間:2分鍾
優化后
SELECT COUNT(subquery.JobID) JobNoCount, SISendUser, MAX(SenderName) SendUserName, LocalName, SUM(MasterBillID) MasterBillCopies, SUM(TEU) TEU FROM ( SELECT job.jobid ,MAX(bill.SISendTime) SISendTime ,MAX(bill.SISendUser) SISendUser ,MAX(con.FIRST_NAME) SenderName ,MAX(cu.LocalName) LocalName ,count (bill.MasterBillID) MasterBillID -- 這里調用自定義函數查詢 性能比較慢 --,COnvert(DECIMAL,dbo.GetContainerTEU(job.jobid)) TEU ,( --把自定義函數中的代碼提取出來 select convert(DECIMAL,sum(b.TEU)) FROM oxContainer ta left join StContainer b on ta.ContainerType = b.ISOCode where ta.JobID = job.JobID ) TEU FROM oxjob job LEFT JOIN oxorder ox ON ox.JobID = job.JobID LEFT JOIN dbo.oxMasterBill bill ON bill.JobID = job.JobID LEFT JOIN dbo.CuCustomer cu ON cu.CustomerID = ox.CarrierCode LEFT JOIN dbo.CONTACT con ON con.CONTACT_GID=bill.SISendUser WHERE CONVERT(char(10),bill.SISendTime,120) BETWEEN '2020-04-08' AND '2020-04-24' GROUP BY job.JobID ) subquery GROUP BY subquery.SISendUser,subquery.LocalName
執行時間:1秒都不到
自定義函數
SET QUOTED_IDENTIFIER ON SET ANSI_NULLS ON GO CREATE function [com].[GetContainerTEU] (@JobID uniqueidentifier) returns nvarchar(4000) as begin declare @rtn nvarchar(4000) select @rtn = '' select @rtn = convert(varchar(50),sum(b.TEU)) from oxContainer a left join StContainer b on a.ContainerType = b.ISOCode where a.JobID = @JobID return @rtn end GO
總結
- 自定義函數沒有辦法建立函數索引,這樣導致查詢結果很慢。
- 自定義函數的性能比較差,能不用的情況盡量不要用。
- 能用存儲過程,就不用自定義函數。
以上屬於個人總結,如有不足之處,希望可以留言哦!