複製代碼 代碼如下:--代碼一DECLARE @cc INT
SELECT NewsId,ROW_NUMBER() OVER(ORDER BY SortNum DESC) AS RowIndex INTO #tb FROM news WITH(NOLOCK) WHERE NewsTypeId=@NewsTypeId AND IsShow=1
SET @cc = @@ROWCOUNT
SELECT n.* FROM news AS n WITH(NOLOCK), #tb As t WHERE t.RowIndex>@PageIndex*@PageSize AND t.RowIndex<=(@PageIndex+1)*@PageSize AND t.newsid=n.newsid
SELECT @cc
DROP TABLE #tb
複製代碼 代碼如下:--代碼二
DECLARE @cc INT
SELECT NewsId,ROW_NUMBER() OVER(ORDER BY SortNum DESC) AS RowIndex INTO #tb FROM news WITH(NOLOCK) WHERE NewsTypeId=@NewsTypeId AND IsShow=1
SET @cc = @@ROWCOUNT
SELECT NewsId INTO #tb2 FROM #tb As t WHERE t.RowIndex>@PageIndex*@PageSize AND t.RowIndex<=(@PageIndex+1)*@PageSize
SELECT * FROM news WITH(NOLOCK) WHERE NewsId IN (SELECT * FROM #tb2)
SELECT @cc
DROP TABLE #tb
DROP TABLE #tb2
答案是代碼二遠遠高於代碼一。在代碼一中加粗代碼的操作會引起整表掃描,因為資料庫引擎在認為WHERE運算式中滿足條件記錄大於一定閥值的時候,就不再去進行查詢最佳化,而直接使用表掃描。看執行資訊,:
表 'news'。掃描計數 1,邏輯讀取 342 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。
(98361 行受影響)
(1 行受影響)
(40 行受影響)
表 '#tb________________________________________00000004C024'。掃描計數 1,邏輯讀取 257 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。
表 'news'。掃描計數 1,邏輯讀取 2805 次,物理讀取 0 次,預讀 235 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。
(1 行受影響)
(1 行受影響)
原本,我想的執行計畫,加粗部分的代碼應該是聚焦索引尋找,這樣效能就提高很多。看代碼二:
表 'news'。掃描計數 1,邏輯讀取 342 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。
(98361 行受影響)
(1 行受影響)
表 '#tb____________________________________00000004BEEF'。掃描計數 1,邏輯讀取 257 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。
(40 行受影響)
(1 行受影響)
(40 行受影響)
表 'news'。掃描計數 0,邏輯讀取 131 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。
表 '#tb2___________________________________00000004BEF0'。掃描計數 1,邏輯讀取 2 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。
(1 行受影響)
(1 行受影響)
很明顯,代碼二與代碼一中的IO運算元大大降低。且代碼一隨著@PageIndex越來越大,效率會越來越低;但代碼二的效率不會隨@PageIndex變化而改變。