已經有快2個月沒有更新博客了,實在是因為最近發生了太多的事情,辭了工作,在湘雅醫院待了一個多月,然後又新換了工作...... 在平時的工作中,Sqlserver中許多知識點是經常用到的,但是有時候我們往往忽略了它們,在過去的一年裡,一直使用的是Mysql,現在又開始接觸Sqlserver了,所以就把 ...
已經有快2個月沒有更新博客了,實在是因為最近發生了太多的事情,辭了工作,在湘雅醫院待了一個多月,然後又新換了工作......
在平時的工作中,Sqlserver中許多知識點是經常用到的,但是有時候我們往往忽略了它們,在過去的一年裡,一直使用的是Mysql,現在又開始接觸Sqlserver了,所以就把一些常用又容易忽視的Sqlserver知識點總結一點,以便備忘之用。
所有的操作都將基於Northwind資料庫來進行操作。
SET NOCOUNT ON 介紹
在存儲過程中,經常用到SET NOCOUNT ON;
作用:阻止在結果集中返回顯示受T-SQL語句或則usp影響的行計數信息。
當SET NOCOUNT ON 時候,不返回計數,當SET NOCOUNT OFF時候,返回計數。
當SET NOCOUNT ON 時候,會更新@@RowCount,但是不向客戶端發送存儲過程每個語句的DONE_IN_proc消息。
如果存儲過程中包含一些並不返回實際數據的語句,使用SET NOCOUNT ON時,網路通信流量便會大量減少,可以顯著提高應用程式性能。
SET NOCOUNT 指定的設置只在執行或運行時候生效,分析時候不生效。
示例:
USE Northwind GO SET NOCOUNT OFF; SELECT TOP 5 OrderDate FROM Orders GO
執行結果如下:
USE Northwind GO SET NOCOUNT ON; SELECT TOP 5 OrderDate FROM Orders GO
執行結果如下:
Go 介紹
如果只是執行一條語句,有沒有GO都一樣。
如果多條語句之間用GO分隔開就不一樣了。
每個被GO分隔的語句都是一個單獨的事務,一個語句執行失敗不會影響其它語句執行。
GO 不是 Transact-SQL 語句;而是可為 SQL Server 查詢分析器識別的命令。
如果你的SQL過長的時候,就要寫GO,或者有一些語句,它只能是第一句操作的,在之前你也得寫 GO ,GO的意思是分批處理語句,有加這個 GO ,就執行GO 行的代碼,執行後再執行接下來的代碼。
像以下這種情況下就要用到GO ,以達到分批處理數據的目的,否則將會報錯。
IF EXISTS(SELECT 1 FROM sys.views WHERE name='View_OrderInfo') DROP VIEW View_OrderInfo create view View_OrderInfo as select c.ContactName,c.CompanyName,o.OrderDate,o.ShipName,o.OrderID,o.Freight from [Orders] o inner join Customers c on o.CustomerID=c.CustomerID
會報錯
必須是:
IF EXISTS(SELECT 1 FROM sys.views WHERE name='View_OrderInfo') DROP VIEW View_OrderInfo GO create view View_OrderInfo as select c.ContactName,c.CompanyName,o.OrderDate,o.ShipName,o.OrderID,o.Freight from [Orders] o inner join Customers c on o.CustomerID=c.CustomerID
select count(*) count(1) count(2) count('a') 之間的區別
count(*):找表中最短的列進行統計行數
count(1) count(2) count('a'):對常數列進行統計行數。它們的執行方式是一樣的,沒有任何區別。
很顯然採用count(1) count(2) count('a')的方式,效率會更高,因為count(*)會先去算出最短的列,然後再去統計。雖然現在的Sqlserver查詢分析器自動會幫我們做一些優化,但是我們必須知道它們的實現原理。
WITH (NOLOCK)
缺點:
1.會產生臟讀
2.只適用與select查詢語句
優點:
1.有些文章說,加了WITH (NOLOCK)的SQL查詢效率可以增加33%。
2.可以用於inner join 或者left join等語句
臟讀: 一個用戶對一個資源做了修改,此時另外一個用戶正好讀取了這條被修改的記錄,然後,第一個用戶放棄修改,數據回到修改之前,這兩個不同的結果就是臟讀。
詳細內容:
要提升SQL的查詢效能,一般來說大家首先會考慮建立索引(index)。其實除了index的建立之外,當我們在下SQL Command時,在語法中加一段WITH (NOLOCK)可以改善線上大量查詢的環境中數據集被LOCK的現象藉此改善查詢的效能。
不過有一點千萬要註意的就是,WITH (NOLOCK)的SQL SELECT有可能會造成Dirty Read(臟讀)。
例如:
SELECT o.OrderID,o.OrderDate,o.Freight,d.Quantity,d.UnitPrice FROM [dbo].[Orders] o WITH (NOLOCK) JOIN [dbo].[Order Details] d WITH (NOLOCK) ON o.OrderID=d.OrderID
DELETE、INSERT、UPDATE這些需要transaction的指令就不能使用WITH (NOLOCK)。
加了WITH (NOLOCK)即告訴SQL Server,我們的這段SELECT指令無需去考慮目前table的transaction lock狀態,因此效能上會有明顯的提升,而且資料庫系統的Lock現象會有明顯的減少(包含Dead Lock)。
當使用NoLock時,它允許閱讀那些已經修改但是還沒有交易完成的數據。因此如果有需要考慮transaction事務數據的實時完整性時,使用WITH (NOLOCK)就要好好考慮一下。
如果不需考慮transaction,WITH (NOLOCK)或許是個好用的參考。