已经有快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)或许是个好用的参考。