国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

SQL Server超時診斷和調(diào)優(yōu)

Original 2016-11-05 16:18:04 705
abstract:SQL Server超時診斷和調(diào)優(yōu)一、 超時分析下面是用戶訪問一個Web站點(diǎn)的常見錯誤:詳細(xì)錯誤描述如下:[SqlException (0x80131904): Timeout expired. The timeout period elapsed prior to completion 

SQL Server超時診斷和調(diào)優(yōu)

一、 超時分析

下面是用戶訪問一個Web站點(diǎn)的常見錯誤:

2642564505-57f90b0a612e7_articlex.jpg

詳細(xì)錯誤描述如下:

[SqlException (0x80131904): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.] System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) +1948826
System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) +4844747
System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj) +194
System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) +2392
System.Data.SqlClient.SqlDataReader.ConsumeMetaData() +33
System.Data.SqlClient.SqlDataReader.get_MetaData() +83
System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) +297
System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) +954
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) +162
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) +32
System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) +141
System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior) +12
System.Data.Common.DbCommand.ExecuteReader() +12
System.Data.Linq.SqlClient.SqlProvider.Execute(Expression query, QueryInfo queryInfo, IObjectReaderFactory factory, Object[] parentArgs, Object[] userArgs, ICompiledSubQuery[] subQueries, Object lastResult) +332

以上輸出非常清晰的描述了,對于這個操作的超時時間結(jié)束,而實際上工作并沒有完成。


我們常常會發(fā)現(xiàn)“timeout”錯誤,那么具體是在哪個訪問階段、受哪個設(shè)置影響報出來的呢?下面,我們通過典型的Web應(yīng)用架構(gòu)來分析下超時問題。

1.png

結(jié)合上面的訪問關(guān)系圖,可以看到:我們從數(shù)據(jù)庫實例的角度出發(fā),它會收到來自Web端的訪問、用戶的直接訪問,它也可能同時訪問其他數(shù)據(jù)庫實例。那么,連接就分為傳入連接(Incoming connection)訪問和傳出連接(Outgoing connection)訪問。那我們根據(jù)就根據(jù)不同階段的訪問來分類超時問題。

傳入連接Web端訪問超時


首先,針對傳入連接,我們來看看Web端的訪問超時:有ASP.NET請求超時、WebService請求超時、IIS請求超時、數(shù)據(jù)庫連接超時和查詢超時。


ASP.NET請求超時


ASP.NET頁面的運(yùn)行超時時間可以在多個地方設(shè)置。


來自MSDN的解釋:

httpRuntime是配置asp.Net http運(yùn)行時設(shè)置,以確定如何處理對asp.Net應(yīng)用程序的請求。

executionTimeout:表示允許執(zhí)行請求的最大時間限制,單位為秒。默認(rèn)值為90秒。

maxRequestLength:指示 ASP.Net 支持的最大文件上載大小。該限制可用于防止因用戶將大量文件傳遞到該服務(wù)器而導(dǎo)致的拒絕服務(wù)攻擊。指定的大小以 KB 為單位。默認(rèn)值為 4096 KB (4 MB)。


1. 全局超時時間

服務(wù)器上如果有多個網(wǎng)站,希望統(tǒng)一設(shè)置一下超時時間,則需要設(shè)置 Machine.config 文件中的 ExecutionTimeout 屬性值。Machine.config 文件位于 %SystemRoot%\Microsoft.NET\Framework\%VersionNumber%\CONFIG\ 目錄中。

例如:

<httpRuntime executionTimeout="90" maxRequestLength="4096" useFullyQualifiedRedirectUrl="false" minFreeThreads="8" minLocalRequestFreeThreads="4" appRequestQueueLimit="100" />

2. 單個站點(diǎn)超時時間

Web.config配置文件中設(shè)置http請求運(yùn)行時間:

<system.web>
<httpRuntime maxRequestLength="102400" executionTimeout="720" />
</system.web>

這里設(shè)置的為720秒,前面的屬性maxRequestLength一般用于用戶上傳文件限制大?。∧J(rèn)一般為4096 KB (4 MB)。


3. 單個頁面請求超時時間

對于單個頁面,可以使用Server.ScriptTimeout來設(shè)定超時。

Server.ScriptTimeout = 120;

注意:如果在Web.config里設(shè)置了debug屬性,例如:

<compilation debug="true" targetFramework="4.0">

此時,ScriptTimeout會被忽略。


WebService請求超時


擴(kuò)大代理類的超時限制,默認(rèn)是90秒,即在調(diào)用方法前指定超時時間。

YourWebService yws = new YourWebService();
yws.Timeout = 1200000; //20分鐘,單位是毫秒

如果將 Timeout 屬性設(shè)置為 Timeout.Infinite,則指示該請求無超時。即使 XML Web services 客戶端可以將 Timeout 屬性設(shè)置為無超時,Web 服務(wù)器仍可以在服務(wù)器端使請求超時。


IIS請求超時


在IIS Manager中,選中Sites,點(diǎn)擊右側(cè)的Website Defaults,在Limits屬性列表中,設(shè)置連接超時時間Connection Time-out(seconds)。默認(rèn)值為120秒。

2642564505-57f90b0a612e7_articlex.jpg

連接超時有助于減少由空閑連接消耗的處理資源損失。啟用連接超時時,IIS 會在連接級別執(zhí)行以下類型的連接超時:客戶端已向服務(wù)器發(fā)送了數(shù)據(jù),現(xiàn)處于空閑狀態(tài)造成的連接超時。


已建立了與服務(wù)器的連接,但客戶端未發(fā)送數(shù)據(jù)時造成的服務(wù)器偵聽超時。響應(yīng)超時(基于可配置的最小字節(jié)數(shù)/秒的值)。請求超時,它禁止客戶端向服務(wù)器發(fā)送不合理的慢速請求(例如,1 比特/秒)。


數(shù)據(jù)庫連接超時


在.NET的SqlConnection類,有ConnectionTimeout屬性,獲取終止嘗試并生成錯誤之前在嘗試建立連接時所等待的時間。等待連接打開所需的時間(以秒為單位)。 默認(rèn)值為 15 秒。在這個時間內(nèi),如果連接沒有建立,我們將會看到這個錯誤。值為0表示無限制。


主要通過連接字符串中的Connect Timeout來進(jìn)行控制,如下:

<connectionStrings>
<add name="conn" connectionString="user id=crm;Password=crmpwd;initial catalog=DBName;Server=DBServerFQDN;Connect Timeout=30;" providerName="System.Data.SqlClient" />
</connectionStrings>

數(shù)據(jù)庫查詢超時


在.NET的SqlCommand類,有CommandTimeout屬性,獲取或設(shè)置在終止嘗試執(zhí)行命令并生成錯誤之前的等待時間。等待命令執(zhí)行所需的時間(以秒為單位)。 默認(rèn)值為 30 秒。如果請求正在運(yùn)行,并且沒有在超時時間內(nèi)完成,那么我們將看到這個錯誤。值為0表示無限制。

主要是通過SqlCommand.CommandTimeout來進(jìn)行控制。如下:

SqlCommand command = new SqlCommand(queryString, connection);
// Setting command timeout to 1 second
command.CommandTimeout = 1;

   


我們另外再介紹一種超時,在.NET的SqlBulkCopy類,有BulkCopyTimeout屬性,超時之前操作完成所允許的秒數(shù)。如果操作超時,事務(wù)便不會提交,而且所有已復(fù)制的行都會從目標(biāo)表中移除。使用SqlBulkCopy批量加載數(shù)據(jù)時的默認(rèn)超時設(shè)置為30秒。


每次對數(shù)據(jù)庫連接時,我們有時候會碰到連接超時或者命令超時,這兩個超時是不一樣的。以ADO.NET為例,當(dāng)客戶端和服務(wù)器端連接時,碰到的超時情況主要有下面幾種:

當(dāng)從連接池獲取一個連接時,碰到超時。

當(dāng)建立一個全新連接(而不是從連接池獲?。r,碰到超時。

當(dāng)發(fā)送一個命令(command)到SQL Server時,超時。

當(dāng)發(fā)送命令(連接字符串帶有“context connection=true”屬性)到SQL Server時,超時。

當(dāng)不是顯示的發(fā)送一個命令(implicitly)到SQL Server時,碰到超時。

當(dāng)執(zhí)行異步命令時,(BeginExecute)碰到超時。

當(dāng)從服務(wù)器端,獲取行時,碰到超時。

當(dāng)用Bulk copy方式,上傳數(shù)據(jù)時,碰到超時。


這些超時主要是通過連接字符串中的Connect Timeout和SqlCommand.CommandTimeout來進(jìn)行控制。前面兩種是登錄超時由Connection Timeout來決定什么時候超時,后面幾種是命令超時由Command Timeout來決定什么時候超時。


特別注意:“超時時間已到。在操作完成之前超時時間已過或服務(wù)器未響應(yīng)”。類似這種錯誤,一般是SqlCommand.CommandTimeout或者SqlBulkCopy.BulkCopyTimeout的時間超時,而不是SqlConnection.ConnectionTimeout。


傳入連接SSMS訪問超時


接著,針對傳入連接,我們來看看用戶通過SQL Server Management Studio即SSMS訪問數(shù)據(jù)庫時的超時設(shè)置。

1.png

QQ圖片20161105135130.png

這里,我們可以設(shè)置SSMS工具的連接和查詢超時時間。連接超時的默認(rèn)值為15秒。而查詢超時的默認(rèn)值為0,表示查詢會一直運(yùn)行直到完成。


傳出連接數(shù)據(jù)庫跨實例遠(yuǎn)程訪問超時


最后,針對傳出連接,我們來看看數(shù)據(jù)庫跨實例遠(yuǎn)程訪問的超時設(shè)置。

數(shù)據(jù)庫從一個實例訪問到另一個實例,可以通過以下方式查看到。


查看配置選項的設(shè)置

sp_configure

1.png

遠(yuǎn)程登錄超時


遠(yuǎn)程登錄超時選項指定了,從登錄遠(yuǎn)程服務(wù)器失敗返回前等待的秒數(shù)。例如,如果你嘗試登錄到一個遠(yuǎn)程服務(wù)器,而服務(wù)器宕機(jī)了,遠(yuǎn)程登錄超時幫助你在你的機(jī)器停止嘗試登錄前,不用無限等待下去。這個選項的默認(rèn)值為10秒。值為0表示無限等待。


在SQL Server 2008中,這個選項的默認(rèn)值為20秒。


遠(yuǎn)程登錄超時選項影響了異構(gòu)查詢的OLE DB提供者產(chǎn)生的連接。


這個設(shè)置不用重啟服務(wù)立即生效。

2642564505-57f90b0a612e7_articlex.jpg

SQL Server 2014的遠(yuǎn)程登錄超時時間默認(rèn)為10秒。下面的腳本可以修改該值:

EXEC sp_configure 'remote login timeout', 35 ;
GO
RECONFIGURE ;
GO


遠(yuǎn)程查詢超時


遠(yuǎn)程查詢超時選項指定了,在SQL Server超時前一個遠(yuǎn)程操作花費(fèi)了多少秒。默認(rèn)值為600秒,允許10分鐘的等待。這個值應(yīng)用于數(shù)據(jù)庫引擎發(fā)起的作為遠(yuǎn)程查詢的傳出連接。這個值對于數(shù)據(jù)庫引擎收到的查詢無效。為了禁止超時,可以設(shè)置為為0。那么查詢將會一直等待直到取消。

對于異構(gòu)查詢,遠(yuǎn)程查詢超時指定了,在查詢超時前,一個遠(yuǎn)程提供者應(yīng)該等待結(jié)果的秒數(shù)。(使用DBPROP_COMMANDTIMEOUT行集屬性在命令對象初始化)。如果被遠(yuǎn)程提供者支持,這個值也被用戶設(shè)置DBPROP_COMMANDTIMEOUT。在指定的數(shù)秒后,這將導(dǎo)致任何其他的操作超時。

對于遠(yuǎn)程存儲過程,遠(yuǎn)程查詢超時指定的秒數(shù)為,在遠(yuǎn)程存儲過程超時之前,在發(fā)送一個遠(yuǎn)程EXEC語句之后花費(fèi)的時間。

這個設(shè)置不用重啟服務(wù)立即生效。

2642564505-57f90b0a612e7_articlex.jpg

SQL Server 2014的遠(yuǎn)程查詢超時為10分鐘,可以通過以下腳本修改該值:

EXEC sp_configure 'remote query timeout', 0 ;
GO
RECONFIGURE ;
GO

   


遠(yuǎn)程服務(wù)器和鏈接服務(wù)器的對應(yīng)選項


在配置遠(yuǎn)程訪問的時候,可以設(shè)置鏈接服務(wù)器的超時選項,也分連接超時和查詢超時。


設(shè)置語法如下:

sp_serveroption [@server = ] 'server'
,[@optname = ] 'option_name'
,[@optvalue = ] 'option_value' ;

   1.png

二、 數(shù)據(jù)庫側(cè)超時診斷和調(diào)優(yōu)


傳入連接連接超時


對于連接超時,首先可以查看Connectivity Ring Buffer中的LoginTimers類型錯誤來分析,如果想獲得更詳盡的信息,再通過抓包工具network monitor。


SQL Server 2008中包含一個新功能,旨在幫助解決特別棘手的連接問題。這個新功能是Connectivity Ring Buffer,它可以捕捉每一個由服務(wù)器發(fā)起的連接關(guān)閉記錄(server-initiated connection closure),包括每一個session或登錄失敗事件。為了進(jìn)行有效的故障排除,Ring Buffer會嘗試提供客戶端的故障和服務(wù)器的關(guān)閉動作之間的關(guān)系信息。只要服務(wù)器在線, 最高1K的Ring Buffer就會被保存,1000條記錄后,Buffer開始循環(huán)覆蓋,即從最老的記錄開始覆蓋。Connectivity Ring Buffer的記錄是能夠使用DMV查詢的:

SELECT CAST(record AS XML) FROM sys.dm_os_ring_buffers
WHERE ring_buffer_type = 'RING_BUFFER_CONNECTIVITY'


首先我們從連接的Ring Buffer數(shù)據(jù)返回的XML來入手。執(zhí)行上面的語句,得到下面的結(jié)果:

2642564505-57f90b0a612e7_articlex.jpg

點(diǎn)擊XML的超鏈接,打開文件內(nèi)容看到更可讀的內(nèi)容,包括一條基本的Ring Buffer連接超時記錄。

2642564505-57f90b0a612e7_articlex.jpg

可以看到在XML文檔中有許多相當(dāng)有用的信息。像SniConsumerError,State和RemoteHost這些。


特別注意的是,RecordType節(jié)點(diǎn),對于我們上面的截圖來看標(biāo)識為“LoginTimers”,說明是連接超時信息。為了識別這種類型的連接Ring Buffer,我們可以查詢SniConsumerError代碼號,準(zhǔn)確定位是什么錯誤導(dǎo)致的。


RecordType包含那些值?

Error – 連接錯誤

LoginTimers – 連接超時

ConnectionClose – 殺掉進(jìn)程


可以通過如下腳本,將XML數(shù)據(jù)轉(zhuǎn)化為可讀信息:

;WITH RingBufferConnectivity as
( SELECT
records.record.value('(/Record/@id)[1]', 'int') AS [RecordID],
records.record.value('(/Record/ConnectivityTraceRecord/RecordType)[1]', 'varchar(max)') AS [RecordType],
records.record.value('(/Record/ConnectivityTraceRecord/RecordTime)[1]', 'datetime') AS [RecordTime],
records.record.value('(/Record/ConnectivityTraceRecord/SniConsumerError)[1]', 'int') AS [Error],
records.record.value('(/Record/ConnectivityTraceRecord/State)[1]', 'int') AS [State],
records.record.value('(/Record/ConnectivityTraceRecord/Spid)[1]', 'int') AS [Spid],
records.record.value('(/Record/ConnectivityTraceRecord/RemoteHost)[1]', 'varchar(max)') AS [RemoteHost],
records.record.value('(/Record/ConnectivityTraceRecord/RemotePort)[1]', 'varchar(max)') AS [RemotePort],
records.record.value('(/Record/ConnectivityTraceRecord/LocalHost)[1]', 'varchar(max)') AS [LocalHost]
FROM
( SELECT CAST(record as xml) AS record_data
FROM sys.dm_os_ring_buffers
WHERE ring_buffer_type= 'RING_BUFFER_CONNECTIVITY'
) TabA
CROSS APPLY record_data.nodes('//Record') AS records (record)
)
SELECT RBC.*, m.text
FROM RingBufferConnectivity RBC
LEFT JOIN sys.messages M ON
RBC.Error = M.message_id AND M.language_id = 1033
WHERE RBC.RecordType='Error' --Comment Out to see all RecordTypes
ORDER BY RBC.RecordTime DESC

執(zhí)行上面的查詢后,將得到下面的可讀結(jié)果。在這個查詢中,我們關(guān)聯(lián)Ring Buffer數(shù)據(jù)和sys.messages視圖去抓取Error id的文本。通過這個信息我們可以跟蹤到精確的導(dǎo)致Error:Login失敗的信息。

2642564505-57f90b0a612e7_articlex.jpg

傳入連接查詢超時


對于查詢超時,針對SQL Server 2012以下的版本,使用Profiler的TSQL_Duration模板的基礎(chǔ)上,添加“Errors and Warnings”下的“Attention”,根據(jù)捕獲到的Attention結(jié)合上下文去查找相應(yīng)的語句;

對于SQL Server 2012及以上版本,直接使用擴(kuò)展事件監(jiān)控sqlserver.attention事件,直接輸出sql_text。


以下為XE腳本:

use tempdb
go
if exists (select * from sys.objects where name = 'sqlws_xev_attention')
drop view sqlws_xev_attention
go
create view sqlws_xev_attention as
with xevents (event_data)
as
(
select event.query('.') as event_data from
((select cast (xest.target_data as xml) as target_data
from sys.dm_xe_sessions as xes
inner join sys.dm_xe_session_targets as xest on (xes.address = xest.event_session_address)
where xes.name = 'sqlws_xevents_attention' and xest.target_name = 'ring_buffer') as td
cross apply target_data.nodes ('//event[@name="attention"]') as x (event))
)
select event_data.value ('(event/@name)[1]', 'varchar(max)') as event_name,
event_data.value ('(event/@timestamp)[1]', 'datetime') as event_timestamp,
event_data.value ('(event/data[@name="duration"]/value)[1]', 'bigint') as [duration],
event_data.value ('(event/data[@name="request_id"]/value)[1]', 'int') as [request_id],
event_data.value ('(event/action[@name="client_app_name"]/value)[1]', 'nvarchar(max)') as action_client_app_name,
event_data.value ('(event/action[@name="client_hostname"]/value)[1]', 'nvarchar(max)') as action_client_hostname,
event_data.value ('(event/action[@name="database_name"]/value)[1]', 'nvarchar(max)') as action_database_name,
event_data.value ('(event/action[@name="nt_username"]/value)[1]', 'nvarchar(max)') as action_nt_username,
event_data.value ('(event/action[@name="session_id"]/value)[1]', 'int') as action_session_id,
event_data.value ('(event/action[@name="sql_text"]/value)[1]', 'nvarchar(max)') as action_sql_text
from xevents
go
if exists (select * from sys.server_event_sessions where name = 'sqlws_xevents_attention')
drop event session sqlws_xevents_attention on server
go
create event session sqlws_xevents_attention on server
add event sqlserver.attention (action (sqlserver.client_app_name, sqlserver.client_hostname, sqlserver.database_name, sqlserver.nt_username, sqlserver.session_id, sqlserver.sql_text) where duration > 5000 )
add target package0.ring_buffer
with (event_retention_mode = ALLOW_SINGLE_EVENT_LOSS, memory_partition_mode = NONE)
go
/*
alter event session sqlws_xevents_attention on server state = start
go
--Execute your workload
with xevents (event_name)
as
(
select event.value ('(@name)[1]', 'varchar(max)') as event_name
from ((select cast (xest.target_data as xml) as target_data
from sys.dm_xe_sessions as xes
inner join sys.dm_xe_session_targets as xest on (xes.address = xest.event_session_address)
where xes.name = 'sqlws_xevents_attention' and xest.target_name = 'ring_buffer') as td
cross apply target_data.nodes ('//event[@name="attention"]') as x (event))
)
select event_name, count(*) from xevents
group by event_name
go
select * from sqlws_xev_attention
go
alter event session sqlws_xevents_attention on server state = stop
go
*/

調(diào)優(yōu)建議

對于連接耗時,當(dāng)然務(wù)必要找到具體原因,是網(wǎng)絡(luò)問題還是驗證問題;對于查詢超時,多為語句性能問題導(dǎo)致,如阻塞、未使用合理的索引、輸出數(shù)據(jù)量太大等原因。對于臨時解決問題,可以在連接配置里、或在程序里的語句級參數(shù)屬性調(diào)大配置值。應(yīng)及時找出問題的根源并解決。

傳出連接數(shù)據(jù)庫跨實例遠(yuǎn)程訪問超時

鏈接服務(wù)器遠(yuǎn)程訪問導(dǎo)致的連接超時和查詢超時,我們可以在目標(biāo)數(shù)據(jù)庫服務(wù)器上來使用以上方法來監(jiān)控和分析。


調(diào)優(yōu)建議

當(dāng)使用鏈接服務(wù)器(Linked Servers)時,最昂貴的代價就是網(wǎng)絡(luò)帶寬間大量數(shù)據(jù)的傳輸。在正確的服務(wù)器書寫正確的代碼是非常重要的,因為每一個錯誤都會導(dǎo)致在網(wǎng)絡(luò)帶寬上付出非 常昂貴的代價。

盡量避免使用鏈接服務(wù)器向遠(yuǎn)程推送數(shù)據(jù),而是使用LinkedServer.DatabaseName.dbo.TableName為源從遠(yuǎn)程拉取數(shù)據(jù)。

跨服務(wù)器查詢時,為了在兩臺服務(wù)器之間的數(shù)據(jù)集之間執(zhí)行JOIN操作,SQL Server需要將數(shù)據(jù)從一臺服務(wù)器傳送到另外一臺服務(wù)器。如果傳送的數(shù)據(jù)是一個非常大的表,這個過程可能會非常痛苦。通常來說,數(shù)據(jù)會從遠(yuǎn)程服務(wù)器傳送到本地服務(wù)器。為了防止大量數(shù)據(jù)在服務(wù)器之間大傳送,你可以通過在查詢條件中過濾數(shù)據(jù),通過一個遠(yuǎn)程存儲過程只取回相關(guān)數(shù)據(jù)來達(dá)到目的,萬一你需要使用INNER JOIN關(guān)聯(lián)兩個不同服務(wù)器之間的數(shù)據(jù)集,而且本地表的數(shù)據(jù)量遠(yuǎn)小于遠(yuǎn)程服務(wù)器的那個表。你可以使用REMOTE JOIN HINT,這樣就會將數(shù)據(jù)從本地服務(wù)器將數(shù)據(jù)傳送到遠(yuǎn)程服務(wù)器,從而提高性能。

正如JOIN操作,UNIION不同服務(wù)器之間的兩個數(shù)據(jù)集必定導(dǎo)致從遠(yuǎn)程服務(wù)器傳送數(shù)據(jù)到本地服務(wù)器。即使你執(zhí)行遠(yuǎn)程查詢合并(UNION)同一個遠(yuǎn)程服務(wù)器的兩個數(shù)據(jù)集,還是會先將兩個數(shù)據(jù)集傳送到本地服務(wù)器,然后UNION兩個數(shù)據(jù)集,可以通過遠(yuǎn)程存儲過程,函數(shù)或視圖先UNION數(shù)據(jù)庫來阻止這個。

避免書寫太復(fù)雜的查詢語句。優(yōu)化器不能總是能明白你需要做什么,尤其是你的SQL語句中使用了鏈接服務(wù)器時,保持SQL腳本簡單。

當(dāng)數(shù)據(jù)庫位于同一個實例時不要使用鏈接服務(wù)器。而是直接使用跨庫訪問Database.dbo.TableName來訪問。

鏈接服務(wù)器的濫用可能會導(dǎo)致數(shù)據(jù)庫出現(xiàn)很多ASYNC_NETWORK_IO等待事件。你可以通過發(fā)布-訂閱或者作業(yè)將數(shù)據(jù)集(表)數(shù)據(jù)先同步到本地服務(wù)器,然后將SQL腳本中的鏈接服務(wù)器去掉,這樣對SQL查詢性能有非常大的提升,尤其是查詢比較頻繁或數(shù)據(jù)量大的SQL語句。

對于鏈接服務(wù)器的對象調(diào)用,盡量使用同義詞,這樣簡化了管理。


Release Notes

Popular Entries