天天看點

SQL Server-聚焦sp_executesql執行動态SQL查詢性能真的比exec好?

之前我們已經讨論過動态SQL查詢呢?這裡為何再來探讨一番呢?因為其中還是存在一定問題,如标題所言,很多面試題也好或者有些部落格也好都在說在執行動态SQL查詢時sp_executesql的性能比exec好,但是事實真是如此?下面我們來一探究竟。

首先我們建立如下測試表。

接着再來插入資料,如下:

最終查詢為如下測試資料:

SQL Server-聚焦sp_executesql執行動态SQL查詢性能真的比exec好?

接下來我們執行如下兩個SQL查詢語句,執行4次

緊接着我們通過如下SQL語句來查詢緩存計劃。

SQL Server-聚焦sp_executesql執行動态SQL查詢性能真的比exec好?

由上圖可知,我們看到存在兩個查詢計劃且每個執行了4次,也就是說每一次查詢都會重新生成一個新的計劃。清除查詢計劃緩存,通過如下指令:

我們繼續往下走,我們接下來通過EXEC來執行動态SQL查詢,如下,執行查詢完畢後再來看看查詢計劃次數:

SQL Server-聚焦sp_executesql執行動态SQL查詢性能真的比exec好?

這個就不做過多解釋,我們依然要清除查詢計劃緩存,我們再利用sp_executesql來查詢,如下:

SQL Server-聚焦sp_executesql執行動态SQL查詢性能真的比exec好?

對比exec執行動态SQL查詢得到的結果是一模一樣,正如我所示範的,我們有兩個計劃,每個執行次數為4。不是說sp_executesql執行動态SQL查詢會重用計劃緩存麼,這是因為我們沒有正确使用sp_executesql是以導緻SQL引擎無法重用計劃。

當參數值改變為語句是唯一變化時,可以使用sp_executesql代替存儲過程多次執行Transact-SQL語句。 因為Transact-SQL語句本身保持不變,隻有參數值發生變化,是以SQL Server查詢優化器可能會重用為第一次執行生成的執行計劃。

以下是正确參數化的查詢方式,我們在字元串裡面有一些變量,在執行的時候,我們通過其他變量傳遞值給它。

SQL Server-聚焦sp_executesql執行動态SQL查詢性能真的比exec好?

我們看到隻有一個計數為8的計劃,而不是像我們上述那樣運作查詢。 我們也可以隻需要聲明一次,然後我們隻需要在執行之前更改參數的值,如下:

最終查詢計劃緩存次數和上述正确方式一緻。正确使用sp_executesql對于性能非常有利,而且使用sp_executesql還可以為我們提供一些EXEC無法實作的功能。比如如何得到一個表中的行數? 利用EXEC我們需要使用一個臨時表和填充,而用sp_executesql我們隻需要使用一個輸出變量。

SQL Server-聚焦sp_executesql執行動态SQL查詢性能真的比exec好?

當然除了EXEC無法實作的功能外,最重要的一點則是SP_EXECUTESQL能夠防止SQL注入問題。

執行SQL動态查詢SP_EXECUTESQL比EXEC性能更好,使得存儲過程能夠被重用,但是存儲過程能夠被重用的前提則是正确使用參數,使用參數化查詢,否則SP_EXECUTESQL将不會提供任何性能益處。