1.DBLINK性能问题
这个运行居然要40秒以上,后来分析了一下:
解决步骤:
首先执行select guid from tablechangelog where tablename='table' and id<110000,发现时间忽略不计,再次还原到同一台服务器上测试运行,发现只要1秒:
也就是说该SQL语句性能瓶颈在于网络,而不是SQL本身。
既然问题在于网络,那应该可以通过减少数据网络传递来解决部分,登陆到目标服务器上执行此语句,发现只需要1~3秒即可。本来想GUID应该是造成该SQL执行的最大问题,没想到居然是网络问题,既然优化已到达效果,就暂且不用去管GUID了。
后话:
对于sqlserver的执行计划以及I/O、CPU之类的指标看起来实在费劲,与其研究这些,不如靠实证来解决
2.关于GUID和递增性ID带来的问题
出于唯一性和系统维护的要求,在各个表中都存在以下两个字段GUID和ID,ID一般为聚集索引+主键。
出于系统维护的要求,一般都会这样查询:
但是GUID是不做唯一索引的,且即使加了唯一索引,考虑到GUID是无序且过于分散的,如果有几千上万的guid的话,仍是不会走索引的。
关于ID,ID一般是递增的,是不要进行维护即可从数据库中获得的,同时由ado直接返回给前端程序,以便定位和显示。
但是再由sqlserver2000升级到sqlserver2008后,发现返回的@@identtiy明显是错误的,后来查了一下SQLServer2000联机帮助,在一条 INSERT、SELECT INTO 或大容量复制语句完成后,@@IDENTITY 中包含此语句产生的最后的标识值。若此语句没有影响任何有标识列的表,则 @@IDENTITY 返回 NULL。若插入了多个行,则会产生多个标识值,@@IDENTITY 返回最后产生的标识值。如果此语句激发一个或多个执行产生标识值的插入操作的触发器,则语句执行后立即调用 @@IDENTITY 将返回由触发器产生的最后的标识值。若 INSERT 或 SELECT INTO 语句失败或大容量复制失败,或事务被回滚,则 @@IDENTITY 值不会还原为以前的设置。发现通过SELECT IDENT_CURRENT('tablename')能够返回正确的递增值,但是否能获取这个值,不得而知。
从sqlserver2005以后系统提供了NEWSEQUENTIALID (),这个新的guid:
这个guid是由操作系统产生的,但是每个guid都会比前一个guid要大,这即解决了唯一性问题,又解决了排序问题,目前开发人员正准备按这个思路进行修改。
在指定计算机上创建大于先前通过该函数生成的任何 GUID 的 GUID。NEWSEQUENTIALID() 不能在查询中引用。
注:即只能做为数据库列的DEFAULT VALUE,不能执行类似SELECT NEWSEQUENTIALID()的语句只有当计算机没有网卡时,NEWSEQUENTIALID() 生成的 GUID 才在该特定计算机中是唯一的。
注:这句话是错误的,应该是只有只有当计算机有网卡时,生成的GUID才是全球唯一您可以使用 NEWSEQUENTIALID() 生成 GUID 以减少叶级别索引上的页争用。