0
Posted on Tuesday, October 11, 2016 by 醉·醉·鱼 and labeled under
谨以此文纪念我已经“死”去的各种老师,我对不起你们,我都忘记完了。


首先在Excel中建立A2:B7的数据。A8,B8分别是A和B的平均数。

根据协方差公式,C列为A2-$A$8,D列为B2-$B$8,E为C2*D2。最后求和得到118.29。再除以N-1,得到协方差23.658。也可以通过=COVARIANCE.S(A2:A7, B2:B7)直接得到。

然后开始计算样本标准差。可以通过=STDEV.S(A2:A7)直接获得7.9633,这里就不一步步计算了。如下图G1和H1.


根据相关系数公式,可以得到相关系数为=F1/G1/H1 0.655979. 也可以通过=CORREL(A2:A7, B2:B7)得到。但是这里的相关系数和趋势图中的β 0.3731相差挺大的。原来,图中的β是通过=F1/G1/G1 得到的,而G1为A:A的样本标准差。因此,β = 0.3731

由于y=βx+ε,带入A和B的平均值,得到ε为1.3417。

其实,你也可以直接通过=SLOPE(B2:B7, A2:A7)计算β,=INTERCEPT(B2:B7, A2:A7)计算ε。


那最后就是这个决定系数R²。切记,不要和相关系数r混淆了。这里的R²是用来衡量前面相关系数β的准确性的,取值为0到1。数值越大,表示β越准确。计算公式为根据线性公式算出的期望方差除以样本方差。

将A列的各值带入公式y=βx+ε,得到J列,再减去平均值$B$8得到K列。将D列和K列分别平方求和,在用M8/L8即可得到决定系数0.430308。也可以通过=RSQ(B2:B7, A2:A7)得到。

0
Posted on Monday, September 19, 2016 by 醉·醉·鱼 and labeled under ,
Kalen最近参加了24 hours of PASS,主题是《Locking, Blocking, Versions: Concurrency for Maximum Performance》。但实际上只讲了locking的一些基本概念,还有很多没有讲到。不过作为回顾,也是不错的。






  1. 在SQL SERVER,最基本的两种lock是shared lock(S)和exclusive lock(X)
  2. UPDATE lock是一个混合模式,出现在UPDATE/DELETE的查询过程中,可以和shared lock兼容,但是与其他U和X锁不兼容。
  3. 对数据进行修改的时候,U锁会升级成为X锁
  4. 一般情况下,我们讨论的lock是TRANSACTION lock,但除此之外,还有SHARED_TRANSACTION_WORKSPACE (Resource = DATABASE)、
    EXCLUSIVE_TRANSACTION_WORKSPACE (Resource = DATABASE)、游标锁、Session Locks (Resource = DATABASE)。
  5. 对于lock的粒度,可以是ROW(RID or KEY)、PAGE、TABLE、PARTITION、EXTENT、DATABASE
  6. SQL SERVER会在多层上放置lock。比如,修改一条记录,会在TABLE 和 PAGE上方式IX锁,在ROW上放置X锁
  7. sys.dm_tran_locks可以用来查看当前的所有lock
  8. ROW锁会升级为更高级别的锁。遇到过一个案例就是锁升级为page锁,进而导致deadlock。
0
Posted on Tuesday, September 13, 2016 by 醉·醉·鱼 and labeled under

拜读完 https://www.simple-talk.com/sql/t-sql-programming/row-versioning-concurrency-in-sql-server/,快快记录一些东西,方便以后回忆。
  1. READ_COMMITTED_SNAPSHOT 和 SNAPSHOT都是基于snapshot的隔离级别
  2. 两种机制都会复制数据一个version到tempdb
  3. 在物理存储上,每条数据都会增加长度为14bytes的pointer和XSN
  4. pointer会指向之前的version,之前的version又会指向更早的version,直到最早的version。有点想HEAP里出现page split一样。
  5. SNAPSHOT机制减少了lock,增加了tempdb开销,间接增加UPDATE和DELETE的代价
  6. READ_COMMITTED_SNAPSHOT 可以避免脏读。是statement level的snapshot isolation。第二次读是可以读到另外TRAN里提交的改动。
  7. SNAPSHOT 可以避免脏读,不可重复读和幻读。是transaction level的snapshot isolation。第二次读到的和第一次读到的一致。
  8. 由于基于version,reader和writer互不block,但是writer还是会block writer。
  9. 正是由于SNAPSHOT可以重复读,会导致UPDATE CONFLICT。即UPDATE的时候其他session已经提交了改动,这个时候就会UPDATE CONFLICT。
  10. 开启READ_COMMITTED_SNAPSHOT需要关闭所有ACTIVE SESSION。
  11. 开启READ_COMMITTED_SNAPSHOT需要将代码里面的NOLOCK抹掉,并默认为READ COMMITTED隔离级别。
0
Posted on Tuesday, September 13, 2016 by 醉·醉·鱼 and labeled under
项目是用SQLCMD加载文件进行schema部署的,如果部署中间出问题了,会是部分提交,还是全部回滚呢?

创建下面的文件

PRINT 'YES'
GO
update test
set someValue = 987
where id = 1
GO
THROW 51000, 'The record does not exist.', 1;  
GO
PRINT 'YES AGAIN'
GO

测试

sqlcmd -S .\MSSQLSERVER2012 -d event_service -i ./sqlcmd_test.sql -m-1 -r -I -b

结果是,部分提交,和你在SSMS里面一样,即使你加了-b option。
0
Posted on Wednesday, August 31, 2016 by 醉·醉·鱼 and labeled under
时间长了,总能够碰见一些奇葩的case。比如有一个字段是ID,但是数据类型是VARCHAR。这里就潜在问题了。当数据比较小的时候都不会有问题,一旦数据比较大的时候,就会出现下面这个错误。

Msg 248, Level 16, State 1, Line 1
The conversion of the varchar value '10000000000000' overflowed an int column.

可以通过下面一段代码来重现这个问题。


CREATE TABLE #TMP(id varchar(50))

INSERT INTO #TMP (ID) VALUES (10), (10000000000000)

SELECT * FROM #TMP WHERE ID = 10
SELECT * FROM #TMP WHERE ID = 10000000000000

错误就在第一个SELECT的WHERE ID = 10上。默认情况下,SQL SERVER会把varchar转换成为右边的数据类型INT,当试图转换10000000000000就溢出了。所以,你要么显示转换,要么老老实实用正确的数据类型。
0
Posted on Wednesday, August 31, 2016 by 醉·醉·鱼 and labeled under
碰巧遇到一个案例,是需要把一个表的部分数据复制到另外一张表,同时把新生成的ID和原来表的ID都要记录下来。

一种方法是用游标,遍历第一个表,逐条插入。5000条记录还是算快的。但是如果数据量特别大的时候,游标就真心慢了。
另外一种方法就是INSERT INTO...SELECT,再用OUTPUT输出两个ID。 我尝试如下方法:



CREATE TABLE #CUSTOMERS (
ID INT IDENTITY(1,1),
NAME VARCHAR(50),
MEMBERSHIP_ID INT
)

CREATE TABLE #MEMBERSHIPS (
ID INT IDENTITY(1,1),
NAME VARCHAR(50)
)

CREATE TABLE #TMP(
CUSTOMER_ID INT,
MEMBERSHIP_ID INT
)

INSERT INTO #CUSTOMERS(NAME) VALUES ('pHoEnIx'), ('ErIk')

INSERT INTO #MEMBERSHIPS(NAME)
OUTPUT c.ID, INSERTED.ID
INTO #TMP
SELECT c.NAME
FROM #CUSTOMERS c
 
----------------------------------------------
--你会得到下面的错误信息
--Msg 4104, Level 16, State 1, Line 5
--The multi-part identifier "c.ID" could not be bound.
--通过http://sqlblog.com/blogs/jamie_thomson/archive/2010/01/06/merge-and-output-the-swiss-army-knife-of-t-sql.aspx
--你可以通过使用MERGE避免这个问题
----------------------------------------------

MERGE #MEMBERSHIPS
USING (SELECT ID, NAME FROM #CUSTOMERS) AS src
ON (1 = 0) --随意不匹配
WHEN NOT MATCHED THEN
    INSERT (NAME)
    VALUES (src.NAME)
    OUTPUT src.ID, INSERTED.ID
    INTO #TMP;



0
Posted on Tuesday, August 30, 2016 by 醉·醉·鱼 and labeled under ,
SQL SERVER 2016出了一个新功能,就是COMPRESS/DECOMPRESS。运用的是GZIP算法,针对LOB这种类型的数据很有效果。

如下图,创建3个表并插入数据。


直接查看占用的空间,可以看到有无DATA_COMPRESS并没有本质区别。因为DATA_COMPRESSION本来就不支持LOB数据。相反,运用了COMPRESS的压缩率达到了可怕的1.7%。当然实际中压缩率会比这个高。


至于性能上,由于数据压缩了,IO上面的开销很显然会更少,相应地会增加CPU的开销。总体而言,使用了压缩以后读取速度会慢一些(可能是我的CPU太差了)。