亚洲综合原千岁中文字幕_国产精品99久久久久久久vr_无码人妻aⅴ一区二区三区浪潮_成人h动漫精品一区二区三

主頁 > 知識庫 > 和表值函數(shù)連接引發(fā)的性能問題分析

和表值函數(shù)連接引發(fā)的性能問題分析

熱門標(biāo)簽:怎樣把地圖標(biāo)注導(dǎo)入公司地址 廣州人工電銷機器人費用 洛陽外呼系統(tǒng)平臺 電銷機器人被曝光 寧波人工外呼系統(tǒng)有效果嗎 地圖標(biāo)注一個圓圈怎么用 400外呼系統(tǒng)合法 真人語音電銷機器人 如何在地圖標(biāo)注自己店鋪

表值函數(shù)

    SQL Server中提供了類似其他編程語言的函數(shù),而函數(shù)的本質(zhì)通常是一段代碼的封裝,并返回值。在SQL Server中,函數(shù)除了可以返回簡單的數(shù)據(jù)類型之外(Int、Varchar等),還可以返回一個集合,也就是返回一個表。
    而根據(jù)是否直接返回集合或是定義后再返回集合,表值函數(shù)又分為內(nèi)聯(lián)用戶定義表值函數(shù)和用戶定義表值函數(shù)(下文統(tǒng)稱為表值函數(shù),省去“用戶定義”四個字)。

內(nèi)聯(lián)表值函數(shù)
    內(nèi)聯(lián)表值函數(shù)和普通函數(shù)并無不同,唯一的區(qū)別是返回結(jié)果為集合(表),而不是簡單數(shù)據(jù)類型,一個簡單的內(nèi)聯(lián)表值函數(shù)如代碼清單1所示(摘自MSDN)。

CREATE FUNCTION Sales.ufn_CustomerNamesInRegion
( @Region nvarchar(50) )
RETURNS table
AS
RETURN (
SELECT DISTINCT s.Name AS Store, a.City
FROM Sales.Store AS s
INNER JOIN Person.BusinessEntityAddress AS bea 
ON bea.BusinessEntityID = s.BusinessEntityID 
INNER JOIN Person.Address AS a 
ON a.AddressID = bea.AddressID
INNER JOIN Person.StateProvince AS sp 
ON sp.StateProvinceID = a.StateProvinceID
WHERE sp.Name = @Region
);
GO

代碼清單1.一個簡單的表值函數(shù)

用戶定義表值函數(shù)
而用戶定義表值函數(shù),需要在函數(shù)開始時定義返回的表結(jié)構(gòu),然后可以寫任何代碼進行數(shù)據(jù)操作,插入到定義的表結(jié)構(gòu)之后進行返回,一個稍微負責(zé)的用戶定義表值函數(shù)示例如代碼清單2所示(摘自MSDN)。

CREATE FUNCTION dbo.ufnGetContactInformation(@ContactID int) 
RETURNS @retContactInformation TABLE 
( 
-- Columns returned by the function 
ContactID int PRIMARY KEY NOT NULL, 
FirstName nvarchar(50) NULL, 
LastName nvarchar(50) NULL, 
JobTitle nvarchar(50) NULL, 
ContactType nvarchar(50) NULL 
) 
AS 
-- Returns the first name, last name, job title, and contact type for the specified contact. 
BEGIN 
DECLARE 
@FirstName nvarchar(50), 
@LastName nvarchar(50), 
@JobTitle nvarchar(50), 
@ContactType nvarchar(50); 
-- Get common contact information 
SELECT 
@ContactID = BusinessEntityID, 
@FirstName = FirstName, 
@LastName = LastName 
FROM Person.Person 
WHERE BusinessEntityID = @ContactID; 
-- Get contact job title 
SELECT @JobTitle = 
CASE 
-- Check for employee 
WHEN EXISTS(SELECT * FROM Person.Person AS p 
WHERE p.BusinessEntityID = @ContactID AND p.PersonType = 'EM') 
THEN (SELECT JobTitle 
FROM HumanResources.Employee AS e 
WHERE e.BusinessEntityID = @ContactID) 
-- Check for vendor 
WHEN EXISTS(SELECT * FROM Person.Person AS p 
WHERE p.BusinessEntityID = @ContactID AND p.PersonType = 'VC') 
THEN (SELECT ct.Name 
FROM Person.ContactType AS ct 
INNER JOIN Person.BusinessEntityContact AS bec 
ON bec.ContactTypeID = ct.ContactTypeID 
WHERE bec.PersonID = @ContactID) 
 
-- Check for store 
WHEN EXISTS(SELECT * FROM Person.Person AS p 
WHERE p.BusinessEntityID = @ContactID AND p.PersonType = 'SC') 
THEN (SELECT ct.Name 
FROM Person.ContactType AS ct 
INNER JOIN Person.BusinessEntityContact AS bec 
ON bec.ContactTypeID = ct.ContactTypeID 
WHERE bec.PersonID = @ContactID) 
ELSE NULL 
END; 
-- Get contact type 
SET @ContactType = 
CASE 
-- Check for employee 
WHEN EXISTS(SELECT * FROM Person.Person AS p 
WHERE p.BusinessEntityID = @ContactID AND p.PersonType = 'EM') 
THEN 'Employee' 
-- Check for vendor 
WHEN EXISTS(SELECT * FROM Person.Person AS p 
WHERE p.BusinessEntityID = @ContactID AND p.PersonType = 'VC') 
THEN 'Vendor Contact' 
-- Check for store 
WHEN EXISTS(SELECT * FROM Person.Person AS p 
WHERE p.BusinessEntityID = @ContactID AND p.PersonType = 'SC') 
THEN 'Store Contact' 
-- Check for individual consumer 
WHEN EXISTS(SELECT * FROM Person.Person AS p 
WHERE p.BusinessEntityID = @ContactID AND p.PersonType = 'IN') 
THEN 'Consumer' 
-- Check for general contact 
WHEN EXISTS(SELECT * FROM Person.Person AS p 
WHERE p.BusinessEntityID = @ContactID AND p.PersonType = 'GC') 
THEN 'General Contact' 
END; 
-- Return the information to the caller 
IF @ContactID IS NOT NULL 
BEGIN 
INSERT @retContactInformation 
SELECT @ContactID, @FirstName, @LastName, @JobTitle, @ContactType; 
END; 
RETURN; 
END; 
GO

代碼訂單2.表值函數(shù)

為什么要用表值函數(shù)
    看起來表值函數(shù)所做的事情和存儲過程并無不同,但實際上還是有所差別。是因為表值函數(shù)可以被用于寫入其他查詢,而存儲過程不行。此外,表值函數(shù)和Apply操作符聯(lián)合使用可以極大的簡化連接操作。

    如果存儲過程符合下述條件的其中一個,可以考慮重寫為表值函數(shù)。

•存儲過程邏輯非常簡單,僅僅是一個Select語句,不用視圖的原因僅僅是由于需要參數(shù)。
•存儲過程中沒有更新操作。
•存儲過程中沒有動態(tài)SQL。
•存儲過程中只返回一個結(jié)果集。
•存儲過程的主要目的是為了產(chǎn)生臨時結(jié)果集,并將結(jié)果集存入臨時表以供其他查詢調(diào)用。

用戶定義表值函數(shù)的問題

    表值函數(shù)與內(nèi)聯(lián)表值函數(shù)不同,內(nèi)聯(lián)表值函數(shù)在處理的過程中更像是一個視圖,這意味著在查詢優(yōu)化階段,內(nèi)聯(lián)表值函數(shù)可以參與查詢優(yōu)化器的優(yōu)化,比如將篩選條件(Where)推到代數(shù)樹的底部,這意味著可以先Where再Join,從而可以利用索引查找降低IO從而提升性能。
    讓我們來看一個簡單的例子。下面代碼示例是一個簡單的和表值函數(shù)做Join的例子:
    首先我們創(chuàng)建表值函數(shù),分別為內(nèi)聯(lián)表值函數(shù)方式和表值函數(shù)方式,如代碼清單3所示。

--創(chuàng)建表值行數(shù) 
CREATE FUNCTION tvf_multi_Test ( ) 
RETURNS @SaleDetail TABLE ( ProductId INT ) 
AS 
BEGIN 
INSERT INTO @SaleDetail 
SELECT ProductID 
FROM Sales.SalesOrderHeader soh 
INNER JOIN Sales.SalesOrderDetail sod ON soh.SalesOrderID = sod.SalesOrderID 
RETURN 
END 
--創(chuàng)建內(nèi)聯(lián)表值函數(shù) 
CREATE FUNCTION tvf_inline_Test ( ) 
RETURNS TABLE 
AS 
RETURN 
SELECT ProductID 
FROM Sales.SalesOrderHeader soh 
INNER JOIN Sales.SalesOrderDetail sod ON soh.SalesOrderID = sod.SalesOrderID 

代碼清單3.創(chuàng)建兩種不同的函數(shù)

現(xiàn)在,我們使用相同的查詢,對這兩個表值函數(shù)進行Join,代碼如代碼清單4所示。

--表值函數(shù)做Join 
SELECT c.personid , 
Prod.Name , 
COUNT(*) 'numer of unit' 
FROM Person.BusinessEntityContact c 
INNER JOIN dbo.tvf_multi_Test() tst ON c.personid = tst.ProductId 
INNER JOIN Production.Product prod ON tst.ProductId = prod.ProductID 
GROUP BY c.personid , 
Prod.Name 
 
--內(nèi)聯(lián)表值函數(shù)做Join 
SELECT c.personid , 
Prod.Name , 
COUNT(*) 'numer of unit' 
FROM Person.BusinessEntityContact c 
INNER JOIN dbo.tvf_inline_Test() tst ON c.personid = tst.ProductId 
INNER JOIN Production.Product prod ON tst.ProductId = prod.ProductID 
GROUP BY c.personid , 
Prod.Name

代碼清單4.表值函數(shù)和內(nèi)聯(lián)表值函數(shù)做Join

執(zhí)行的成本如圖1所示。

圖1.兩種方式的成本

從IO來看,很明顯是選擇了次優(yōu)的執(zhí)行計劃,BusinessEntityContact選擇了121317次查找,而不是一次掃描。而內(nèi)聯(lián)表函數(shù)能夠正確知道掃描一次的成本遠低于一次查找。

那問題的根源是內(nèi)聯(lián)表值函數(shù),對于SQL Server來說,和視圖是一樣的,這意味著內(nèi)聯(lián)表值函數(shù)可以參與到邏輯執(zhí)行計劃的代數(shù)運算(或者是代數(shù)樹優(yōu)化)中,這意味著內(nèi)斂表可以進一步拆分(如圖1所示,第二個內(nèi)聯(lián)表的查詢,執(zhí)行計劃具體知道內(nèi)斂表中是SalesOrderHeader表和SalesOrderDetail表,由于查詢只選擇了一列,所以執(zhí)行計劃優(yōu)化直到可以無需掃描SalesOrderHeader表),對于內(nèi)聯(lián)表值函數(shù)來說,執(zhí)行計劃可以完整知道所涉及的表上的索引以及相關(guān)統(tǒng)計信息等元數(shù)據(jù)。
另一方面,表值函數(shù),如圖1的第一部分所示,表值函數(shù)對整個執(zhí)行計劃來說是一個黑箱子,既不知道統(tǒng)計信息,也沒有索引。執(zhí)行計劃中不知道表值函數(shù)所涉及的表(圖1中為#AE4E5168這個臨時表,而不是具體的表明),因此對整個執(zhí)行計劃來說該結(jié)果集SQL Server會假設(shè)返回的結(jié)果非常小,當(dāng)表值函數(shù)返回的結(jié)果較多時(如本例所示),則會產(chǎn)生比較差的執(zhí)行計劃。
因此綜上所述,在表值函數(shù)返回結(jié)果極小時,對性能可能沒有影響,但返回結(jié)果如果略多,則一定會影響執(zhí)行計劃的質(zhì)量。

如何處理
首先,在SQL Server中,我們要找出現(xiàn)存的和表值函數(shù)做Join的語句,通過挖掘執(zhí)行計劃,我們可以找出該類語句,使用的代碼如代碼清單5所示。

WITH XMLNAMESPACES('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS p) 
SELECT st.text, 
qp.query_plan 
FROM ( 
SELECT TOP 50 * 
FROM sys.dm_exec_query_stats 
ORDER BY total_worker_time DESC 
) AS qs 
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st 
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) AS qp 
WHERE qp.query_plan.exist('//p:RelOp[contains(@LogicalOp, "Join")]/*/p:RelOp[(@LogicalOp[.="Table-valued function"])]') = 1

代碼清單5.從執(zhí)行計劃緩存中找出和表值函數(shù)做Join的查詢

結(jié)果如圖2所示。

圖2.執(zhí)行計劃緩存中已經(jīng)存在的和表值函數(shù)做Join的查詢

小結(jié)
本文闡述了表值函數(shù)的概念,表值函數(shù)為何會影響性能以及在執(zhí)行計劃緩存中找出和表值函數(shù)做Join的查詢。對于和表值函數(shù)做Apply或表值函數(shù)返回的行數(shù)非常小的查詢,或許并不影響。但對于返回結(jié)果較多的表值函數(shù)做Join,則可能產(chǎn)生性能問題,因此如果有可能,把表值函數(shù)重寫為內(nèi)聯(lián)表值函數(shù)或?qū)⒈碇岛瘮?shù)的結(jié)果存入臨時表再進行Join可提升性能。

參考資料:

http://www.brentozar.com/blitzcache/tvf-join/

http://blogs.msdn.com/b/psssql/archive/2010/10/28/query-performance-and-multi-statement-table-valued-functions.aspx?CommentPosted=true#commentmessage

標(biāo)簽:晉中 珠海 北海 煙臺 東營 南昌 石家莊 咸寧

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《和表值函數(shù)連接引發(fā)的性能問題分析》,本文關(guān)鍵詞  和,表值,函數(shù),連接,引發(fā),;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《和表值函數(shù)連接引發(fā)的性能問題分析》相關(guān)的同類信息!
  • 本頁收集關(guān)于和表值函數(shù)連接引發(fā)的性能問題分析的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    国产福利免费观看| 91麻豆精品国产片在线观看| 久久国产影院| 日韩专区在线播放| 精品国产亚洲一区二区三区| 日本在线www| 91麻豆精品国产自产在线| 亚欧成人毛片一区二区三区四区| 深夜做爰性大片中文| 99久久网站| 欧美一级视频免费| 一级毛片视频在线观看| 成人影院一区二区三区| 中文字幕97| 久久精品大片| 一级毛片视频在线观看| 国产91素人搭讪系列天堂| 99久久精品国产片| 欧美激情一区二区三区中文字幕| 欧美大片aaaa一级毛片| 国产极品精频在线观看| 国产一级生活片| 国产一区二区精品| 精品久久久久久影院免费| 欧美激情一区二区三区在线| 午夜欧美成人香蕉剧场| 国产不卡福利| 日韩女人做爰大片| 91麻豆精品国产自产在线| 国产精品自拍亚洲| 九九久久99综合一区二区| 91麻豆精品国产自产在线观看一区 | 午夜久久网| 国产伦精品一区二区三区无广告| 亚洲精品久久玖玖玖玖| 欧美激情一区二区三区在线播放| 午夜激情视频在线播放| 欧美夜夜骑 青草视频在线观看完整版 久久精品99无色码中文字幕 欧美日韩一区二区在线观看视频 欧美中文字幕在线视频 www.99精品 香蕉视频久久 | 日韩avdvd| 91麻豆国产| 免费一级生活片| 国产激情视频在线观看| 亚洲天堂免费| 黄视频网站免费看| 精品久久久久久影院免费| 九九久久国产精品| 黄色免费三级| 麻豆网站在线看| 国产视频一区在线| 国产伦精品一区二区三区无广告| 91麻豆精品国产自产在线| 高清一级毛片一本到免费观看| 久草免费在线色站| 美女免费精品视频在线观看| 天天做人人爱夜夜爽2020| 麻豆网站在线看| 国产a网| 成人免费一级毛片在线播放视频| 精品视频免费在线| 九九精品在线播放| 亚欧成人乱码一区二区| 中文字幕Aⅴ资源网| 国产a网| 成人影院久久久久久影院| 中文字幕97| 99热精品在线| 99久久精品国产片| a级毛片免费观看网站| 毛片高清| 国产高清在线精品一区二区| 日韩在线观看网站| 成人a大片高清在线观看| 国产一区二区精品| 人人干人人插| 麻豆系列国产剧在线观看| 日韩av东京社区男人的天堂| 日本特黄特色aa大片免费| 久久久成人网| 日韩女人做爰大片| 久久国产精品永久免费网站| 天天色色网| 国产精品1024永久免费视频 | 亚洲爆爽| 久久精品免视看国产明星| 沈樵在线观看福利| 精品视频在线看| 尤物视频网站在线| 亚洲精品永久一区| 四虎影视库| 日韩在线观看视频免费| 国产网站在线| 中文字幕一区二区三区精彩视频| 精品久久久久久中文字幕2017| 日本免费乱人伦在线观看 | 国产不卡在线看| 999精品影视在线观看| 91麻豆国产| 国产高清视频免费观看| 精品国产一区二区三区久| 在线观看成人网 | 欧美1区| 欧美夜夜骑 青草视频在线观看完整版 久久精品99无色码中文字幕 欧美日韩一区二区在线观看视频 欧美中文字幕在线视频 www.99精品 香蕉视频久久 | 午夜家庭影院| 久久国产精品自线拍免费| 国产一区二区福利久久| 午夜欧美成人香蕉剧场| 午夜激情视频在线播放| 日本在线不卡视频| 青青久久精品| 青草国产在线| 亚洲精品影院| 日本久久久久久久 97久久精品一区二区三区 狠狠色噜噜狠狠狠狠97 日日干综合 五月天婷婷在线观看高清 九色福利视频 | 精品在线观看一区| 精品视频一区二区三区免费| 亚洲 国产精品 日韩| 你懂的在线观看视频| 欧美大片一区| 日日爽天天| 韩国毛片免费大片| 亚欧视频在线| 亚欧视频在线| 日韩女人做爰大片| 亚洲wwwwww| 国产伦精品一区二区三区在线观看| 黄色福利片| 国产精品1024永久免费视频| 高清一级片| 亚洲第一视频在线播放| 欧美另类videosbestsex高清| 日韩中文字幕在线亚洲一区| 欧美爱爱动态| 午夜在线亚洲男人午在线| 亚洲女人国产香蕉久久精品| 你懂的日韩| 精品视频在线看 | 黄视频网站在线免费观看| 韩国三级香港三级日本三级| 欧美国产日韩一区二区三区| 国产精品免费久久| 国产视频一区二区三区四区| 欧美激情影院| 国产美女在线一区二区三区| 精品在线视频播放| 国产麻豆精品免费密入口| 国产伦精品一区三区视频| 午夜在线影院| 天堂网中文字幕| 91麻豆精品国产自产在线观看一区 | 黄色短视屏| 99色精品| 欧美日本国产| 青青青草影院 | 精品国产一区二区三区久久久蜜臀 | 成人免费高清视频| 国产网站免费视频| 国产极品精频在线观看| 精品在线观看一区| 国产成人精品影视| 美女免费毛片| 好男人天堂网 久久精品国产这里是免费 国产精品成人一区二区 男人天堂网2021 男人的天堂在线观看 丁香六月综合激情 | 国产激情一区二区三区| 美女免费精品视频在线观看| 99久久网站| 99热精品在线| 青青青草影院 | 日本伦理片网站| 亚洲精品中文字幕久久久久久| 香蕉视频亚洲一级| 国产高清视频免费观看| 欧美大片aaaa一级毛片| 日本久久久久久久 97久久精品一区二区三区 狠狠色噜噜狠狠狠狠97 日日干综合 五月天婷婷在线观看高清 九色福利视频 | 成人在免费观看视频国产| 四虎久久精品国产| 成人高清护士在线播放| 欧美1卡一卡二卡三新区| 日本免费看视频| 欧美国产日韩一区二区三区| 国产一区免费在线观看| 日韩专区第一页| 国产精品自拍一区| 午夜久久网| 成人免费观看的视频黄页| 国产韩国精品一区二区三区| 日韩在线观看免费| 国产91素人搭讪系列天堂| 亚洲天堂免费| 国产视频在线免费观看| 色综合久久久久综合体桃花网| 免费一级片在线观看| 久久久久久久网| 国产一区二区精品久久91| 精品久久久久久中文字幕一区| 免费的黄色小视频| 日本特黄特色aa大片免费| 欧美电影免费| 国产视频久久久久| 久久99青青久久99久久| 日韩在线观看视频黄| 国产高清在线精品一区二区| 久久精品欧美一区二区|