中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

SQL調優的示例分析

發布時間:2021-12-29 09:29:38 來源:億速云 閱讀:144 作者:小新 欄目:軟件技術

這篇文章主要為大家展示了“SQL調優的示例分析”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“SQL調優的示例分析”這篇文章吧。

環境:Microsoft SQL Server 2016 (SP2-CU3)企業版

問題SQL:

select 
	RowNumber = ROW_NUMBER() OVER 
	( 
		-- This ordering is from the various Fulfillment Map sort orders to match the fulfillment app's row order.
		ORDER BY 
			htly.LicenseYear, 
			mht.Name, 
			h.HuntFirstOpenDate, 
			h.DisplayOrder,
			h.HuntCode,
			ci_orderby.LastName,
			ci_orderby.FirstName,
			fmu.FulfillmentMailingUnitID
	),
	ShippingName = ISNULL(fism_aot.ShippingName,  dbo.udf_GetCustomerName(c.CustomerID)),
	FulfillmentMailingUnitID = fmu.FulfillmentMailingUnitID,
	GoID = goid.IdentityValue,
	MailingZip = ISNULL(fism_zc.ZipCode, zc.ZipCode),
	TransactionID = fism_th.TransactionID,
	TransactionHeaderID = fism_th.TransactionHeaderID,
	HuntDate = h.HuntFirstOpenDate,
	HuntCode = h.HuntCode,
	-- Header info
	BatchNumber = fmulg.FulfillmentMailingUnitLockGroupID,
	PrintedByUserName = au.UserName,
	LockedDate = fmulg.LockedDate
from
	dbo.FulfillmentMailingUnitLockGroup fmulg
	cross join dbo.Enum_IdentityType eit
	cross join dbo.Enum_LicenseActionType elat
	inner join dbo.FulfillmentMailingUnitLock fmul
		on fmulg.FulfillmentMailingUnitLockGroupID = fmul.FulfillmentMailingUnitLockGroupID
	inner join dbo.FulfillmentMailingUnit fmu
		on fmul.LockedFulfillmentMailingUnitID = fmu.FulfillmentMailingUnitID
	inner join dbo.ApplicationUser au
		on fmulg.LockedByApplicationUserID = au.ApplicationUserID
	-- Getting to the Transaction Header by FulfillmentInternetSalesMap OR FulfillmentDrawIssuanceMap
	left join dbo.FulfillmentInternetSalesMap fism
		on fmu.FulfillmentMailingUnitID = fism.FulfillmentMailingUnitID
	left join dbo.FulfillmentDrawIssuanceMap fdim
		on fmu.FulfillmentMailingUnitID = fdim.FulfillmentMailingUnitID
		left join dbo.TransactionHeader th	
			on fism.TransactionHeaderID = th.TransactionHeaderID
				or fdim.TransactionHeaderID = th.TransactionHeaderID
	left join dbo.TransactionHeader fdim_th
		on fdim.TransactionHeaderID = fdim_th.TransactionHeaderID
	-- Getting to License from FulfillmentDrawNotificationMap
	left join dbo.FulfillmentDrawNotificationMap fdnm
		on fmu.FulfillmentMailingUnitID = fdnm.FulfillmentMailingUnitID
		left join dbo.DrawTicketLicense fdnm_dtl
			on fdnm.DrawTicketLicenseID = fdnm_dtl.DrawTicketLicenseID 
		left join dbo.License fdnm_l
			on fdnm_dtl.LicenseID = fdnm_l.LicenseID
		left join dbo.DrawTicket fdnm_dt
			on fdnm_dtl.DrawTicketID = fdnm_dt.DrawTicketID
		left join dbo.DrawTicketHuntChoice fdnm_dthc
			on 
				fdnm_dt.DrawTicketID = fdnm_dthc.DrawTicketID
				and
				(
					-- If the draw ticket is a winner, link to the hunt choice that won.
					(fdnm_dt.WasDrawn = 1 and fdnm_dthc.WasDrawn = 1)
					-- Else if the draw ticket was not a winner, link to the first hunt choice since
					-- Losing and Alternate notifications are not valid for multi-choice hunts
					or (fdnm_dt.WasDrawn = 0 and fdnm_dthc.OrderIndex = 1)
				)
		left join dbo.TransactionDetail fdim_td
			on fdim.TransactionHeaderID = fdim_td.TransactionHeaderID
		left join dbo.LicenseAction fdim_la
			on fdim_td.TransactionDetailID = fdim_la.TransactionDetailID
				-- This might be silly since it should only be Issued for issuance... (currently it's sold in the stored proc that issues tags)
				and (fdim_la.LicenseActionTypeID = elat.Sold or fdim_la.LicenseActionTypeID = elat.Issued or fdim_la.LicenseActionTypeID = elat.Duplicated)
		left join dbo.License fdim_l
			on fdim_la.LicenseID = fdim_l.LicenseID
		
		left join dbo.Hunt h
			on fdnm_dthc.HuntID = h.HuntID
				or fdim_l.HuntID = h.HuntID
		left join dbo.HuntTypeLicenseYear htly
			on h.HuntTypeLicenseYearID = htly.HuntTypeLicenseYearID
		left join dbo.MasterHuntType mht
			on htly.MasterHuntTypeID = mht.MasterHuntTypeID
	left join dbo.Customer c
		on fdnm_l.CustomerID = c.CustomerID
			or th.CustomerID = c.CustomerID
	left join dbo.CustomerIndividual ci
		on c.CustomerID = ci.CustomerID
	left join dbo.CustomerIdentity goid
		on c.CustomerID = goid.CustomerID
			and goid.IdentityTypeID = eit.GOID
			and goid.[Status] = 1
	left join dbo.AddressDetail ad
		on c.MailingAddressID = ad.AddressID
			and ad.IsActive = 1
	left join dbo.ZipCode zc
		on ad.ZipCodeID = zc.ZipCodeID
	left join dbo.CustomerIndividual ci_orderby
		on fdnm_l.CustomerID = ci_orderby.CustomerID
			or fdim_th.CustomerID = ci_orderby.CustomerID
	
	left join dbo.TransactionHeader fism_th	
		on fism.TransactionHeaderID = fism_th.TransactionHeaderID
	left join dbo.ActiveOutdoorsTransaction fism_aot
		on fism_aot.TransactionID = fism_th.TransactionID
	left join dbo.AddressDetail fism_ad 
		on fism_aot.ShippingAddressID = fism_ad.AddressID
			and fism_ad.IsActive = 1
	left join dbo.ZipCode fism_zc
		on fism_ad.ZipCodeID = fism_zc.ZipCodeID
	where
		fmulg.FulfillmentMailingUnitLockGroupID = @FulfillmentMailingUnitLockGroupID

該SQL執行192s后出記錄,分析一下sql的執行計劃:

分析一:

最終的排序消耗了大量的cost:

SQL調優的示例分析

分析二:

該SQL存在大量多表連接,MSSQL引擎由于統計信息的算法單一,在處理大量級聯連接時,實際數據可能嚴重偏離統計信息

連接中存在Actual Rows和Estimated Rows嚴重不一致的情況,隨著連接表數目增加,該不一致更加嚴重:

SQL調優的示例分析

經過分析,優化的目標是減少多表連接的統計信息不一致導致的執行計劃錯誤并且對最終的排序操作進行外推。

優化的手法主要是利用臨時表固化統計信息,外推排序:

最終優化SQL:

select 
	fmu.FulfillmentMailingUnitID
	,elat.Sold
	,elat.Issued
	,elat.Duplicated
	,fmulg.FulfillmentMailingUnitLockGroupID
	,au.UserName
	,fmulg.LockedDate
	,eit.GOID
	into #temp
	from 
	dbo.FulfillmentMailingUnitLockGroup fmulg
	cross join dbo.Enum_IdentityType eit
	cross join dbo.Enum_LicenseActionType elat
	inner join dbo.FulfillmentMailingUnitLock fmul
		on fmulg.FulfillmentMailingUnitLockGroupID = fmul.FulfillmentMailingUnitLockGroupID
	inner join dbo.FulfillmentMailingUnit fmu
		on fmul.LockedFulfillmentMailingUnitID = fmu.FulfillmentMailingUnitID
	inner join dbo.ApplicationUser au
		on fmulg.LockedByApplicationUserID = au.ApplicationUserID
	where
		fmulg.FulfillmentMailingUnitLockGroupID = @FulfillmentMailingUnitLockGroupID
	select 
		fdnm_l.CustomerID fdnm_l_CustomerID,
		th.CustomerID th_CustomerID,
		fdim_th.CustomerID fdim_th_CustomerID,
		t.FulfillmentMailingUnitID,
		h.HuntFirstOpenDate,
		h.HuntCode,
		t.FulfillmentMailingUnitLockGroupID,
		t.UserName,
		LockedDate,
		t.GOID,
		htly.LicenseYear, 
		mht.Name, 
		h.DisplayOrder,
		--ci_orderby.LastName,
		--ci_orderby.FirstName,
		fism.TransactionHeaderID
		into #temp1
		from #temp t
	
		-- Getting to the Transaction Header by FulfillmentInternetSalesMap OR FulfillmentDrawIssuanceMap
		left join dbo.FulfillmentInternetSalesMap fism
			on t.FulfillmentMailingUnitID = fism.FulfillmentMailingUnitID
		left join dbo.FulfillmentDrawIssuanceMap fdim
			on t.FulfillmentMailingUnitID = fdim.FulfillmentMailingUnitID
		left join dbo.TransactionHeader th	
			on fism.TransactionHeaderID = th.TransactionHeaderID
				or fdim.TransactionHeaderID = th.TransactionHeaderID
		left join dbo.TransactionHeader fdim_th
			on fdim.TransactionHeaderID = fdim_th.TransactionHeaderID
		-- Getting to License from FulfillmentDrawNotificationMap
		left join dbo.FulfillmentDrawNotificationMap fdnm
			on t.FulfillmentMailingUnitID = fdnm.FulfillmentMailingUnitID
		left join dbo.DrawTicketLicense fdnm_dtl
			on fdnm.DrawTicketLicenseID = fdnm_dtl.DrawTicketLicenseID 
		left join dbo.License fdnm_l
			on fdnm_dtl.LicenseID = fdnm_l.LicenseID
		left join dbo.DrawTicket fdnm_dt
			on fdnm_dtl.DrawTicketID = fdnm_dt.DrawTicketID
		left join dbo.DrawTicketHuntChoice fdnm_dthc
			on 
				fdnm_dt.DrawTicketID = fdnm_dthc.DrawTicketID
				and
				(
					-- If the draw ticket is a winner, link to the hunt choice that won.
					(fdnm_dt.WasDrawn = 1 and fdnm_dthc.WasDrawn = 1)
					-- Else if the draw ticket was not a winner, link to the first hunt choice since
					-- Losing and Alternate notifications are not valid for multi-choice hunts
					or (fdnm_dt.WasDrawn = 0 and fdnm_dthc.OrderIndex = 1)
				)
		left join dbo.TransactionDetail fdim_td
			on fdim.TransactionHeaderID = fdim_td.TransactionHeaderID
		left join dbo.LicenseAction fdim_la
			on fdim_td.TransactionDetailID = fdim_la.TransactionDetailID
				-- This might be silly since it should only be Issued for issuance... (currently it's sold in the stored proc that issues tags)
				and (fdim_la.LicenseActionTypeID = t.Sold or fdim_la.LicenseActionTypeID = t.Issued or fdim_la.LicenseActionTypeID = t.Duplicated)
		left join dbo.License fdim_l
			on fdim_la.LicenseID = fdim_l.LicenseID
	
		left join dbo.Hunt h
			on fdnm_dthc.HuntID = h.HuntID
				or fdim_l.HuntID = h.HuntID
		left join dbo.HuntTypeLicenseYear htly
			on h.HuntTypeLicenseYearID = htly.HuntTypeLicenseYearID
		left join dbo.MasterHuntType mht
			on htly.MasterHuntTypeID = mht.MasterHuntTypeID
	--set statistics io on
	--set statistics time on
	select 
		t1.LicenseYear,
		t1.Name, 
		t1.DisplayOrder,
		c.CustomerID,
		t1.FulfillmentMailingUnitID,
		t1.GOID,
		zc.ZipCode,
		t1.HuntFirstOpenDate,
		t1.HuntCode,
		t1.FulfillmentMailingUnitLockGroupID,
		t1.UserName,
		t1.LockedDate,
		t1.fdnm_l_CustomerID,
		t1.fdim_th_CustomerID,
		t1.TransactionHeaderID
	 into #temp2
	 from #temp1 t1
	
		-- Getting to Cusotmer from the joined transaction header or the license from the DrawTicketLicense
		left join dbo.Customer c
			on t1.fdnm_l_CustomerID = c.CustomerID
				or t1.th_CustomerID = c.CustomerID
		left join dbo.CustomerIndividual ci
			on c.CustomerID = ci.CustomerID
		
		left join dbo.AddressDetail ad
			on c.MailingAddressID = ad.AddressID
				and ad.IsActive = 1
		left join dbo.ZipCode zc
			on ad.ZipCodeID = zc.ZipCodeID
		
	select 
		t2.LicenseYear,
		t2.Name, 
		t2.DisplayOrder,
		ci_orderby.LastName,
		ci_orderby.FirstName,
		ShippingName = ISNULL(fism_aot.ShippingName,  dbo.udf_GetCustomerName(t2.CustomerID)),
		FulfillmentMailingUnitID = t2.FulfillmentMailingUnitID,
		GoID = goid.IdentityValue,
		MailingZip = ISNULL(fism_zc.ZipCode, t2.ZipCode),
		TransactionID = fism_th.TransactionID,
		TransactionHeaderID = fism_th.TransactionHeaderID,
		HuntDate = t2.HuntFirstOpenDate,
		HuntCode = t2.HuntCode,
		-- Header info
		BatchNumber = t2.FulfillmentMailingUnitLockGroupID,
		PrintedByUserName = t2.UserName,
		LockedDate = t2.LockedDate 
	into #temp3
	from #temp2 t2
			left join dbo.CustomerIdentity goid
				on t2.CustomerID = goid.CustomerID
				and goid.IdentityTypeID = t2.GOID 
				and goid.[Status] = 1
			left join dbo.CustomerIndividual ci_orderby
				on t2.fdnm_l_CustomerID = ci_orderby.CustomerID
					or t2.fdim_th_CustomerID = ci_orderby.CustomerID
	
			left join dbo.TransactionHeader fism_th	
				on t2.TransactionHeaderID = fism_th.TransactionHeaderID
			left join dbo.ActiveOutdoorsTransaction fism_aot
				on fism_aot.TransactionID = fism_th.TransactionID
			left join dbo.AddressDetail fism_ad 
				on fism_aot.ShippingAddressID = fism_ad.AddressID
					and fism_ad.IsActive = 1
			left join dbo.ZipCode fism_zc
				on fism_ad.ZipCodeID = fism_zc.ZipCodeID
	select	RowNumber = ROW_NUMBER() OVER 
		( 
			-- This ordering is from the various Fulfillment Map sort orders to match the fulfillment app's row order.
			ORDER BY 
				t3.LicenseYear, 
				t3.Name, 
				t3.HuntDate, 
				t3.DisplayOrder,
				t3.HuntCode,
				t3.LastName,
				t3.FirstName,
				t3.FulfillmentMailingUnitID
		),
		ShippingName,
		FulfillmentMailingUnitID,
		GoID,
		MailingZip,
		TransactionID,
		TransactionHeaderID,
		HuntDate,
		HuntCode,
		-- Header info
		BatchNumber,
		PrintedByUserName,
		LockedDate
	from #temp3 t3
	drop table #temp
	drop table #temp1
	drop table #temp2
	drop table #temp3

經過測試,執行時間由192秒降低到2秒。

以上是“SQL調優的示例分析”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

sql
AI

广西| 万年县| 顺义区| 泗阳县| 汝城县| 民县| 虹口区| 灵石县| 剑川县| 玉门市| 鄢陵县| 民县| 峨边| 枞阳县| 丰原市| 都昌县| 沙田区| 新绛县| 宁海县| 上栗县| 南城县| 安乡县| 游戏| 杭锦后旗| 乐陵市| 寻乌县| 车险| 仁布县| 大英县| 城口县| 保康县| 上饶县| 甘孜| 岑溪市| 汝南县| 苗栗市| 鄂州市| 沧源| 上饶市| 陕西省| 仪征市|