SqlServer优化的一些细节

1. 对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。

2. 应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:
select id from t where num is null
可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:
select id from t where num=0

3. 应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。

4. 应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:
select id from t where num=10 or num=20
可以这样查询:
select id from t where num=10
union all
select id from t where num=20

5. in 和 not in 也要慎用,否则会导致全表扫描,如:
select id from t where num in(1,2,3)
对于连续的数值,能用 between 就不要用 in 了:
select id from t where num between 1 and 3

6. 下面的查询也将导致全表扫描:
select id from t where name like ‘%abc%’
若要提高效率,可以考虑全文检索。

7. 如果在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然 而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描:
select id from t where num=@num
可以改为强制查询使用索引:
select id from t with(index(索引名)) where num=@num

8. 应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:
select id from t where num/2=100
应 改为:
select id from t where num=100*2

9. 应尽量避免在where子句中对字段进行函数 操作,这将导致引擎放弃使用索引而进行全表扫描。如:
select id from t where substring(name,1,3)=’abc’–name以abc开头的id
select id from t where datediff(day,createdate,’2005-11-30′)=0–‘2005-11-30’生成的id
应改为:
select id from t where name like ‘abc%’
select id from t where createdate>=’2005-11-30′ and createdate<'2005-12-1' 10. 不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。 11. 在使用索引字段作为条件 时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与 索引顺序相一致。 12. 不要写一些没有意义的查询,如需要生成一个空表结构: select col1,col2 into #t from t where 1=0 这类代码不会返回任何结果集,但是会消耗系统资源的,应改成这样: create table #t(...) 13. 很多时候用 exists 代替 in 是一个好的选择: select num from a where num in(select num from b) 用下面的语句替换: select num from a where exists(select 1 from b where num=a.num) 14. 并不是所有索引对查询都有效,SQL是根据表中 数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段***,male、female几乎各一半,那么即使 在***上建了索引也对查询效率起不了作用。 15. 索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有 必要。 16. 应尽可能的避免更新 clustered 索引数据列,因为 clustered 索引数据列的顺序就是表记录的物理存储顺序,一旦该列值改变将导致整个表记录的顺序的调整,会耗费相当大的资源。若应用系统需要频繁更新 clustered 索引数据列,那么需要考虑是否应将该索引建为 clustered 索引。 17. 尽量使用数字型字段,若只含数值信 息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字 型而言只需要比较一次就够了。 18. 尽可能的使用 varchar/nvarchar 代替 char/nchar ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。 19. 任何地方都不要 使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。 20. 尽量使用表变量来代替临时表。 如果表变量包含大量数据,请注意索引非常有限(只有主键索引)。 21. 避免频繁创建和删除临时表,以减少系统表资源的消耗。 22. 临时表并不是不可使用,适当地使用它们可以使某些例程更有效,例如,当需要重复引用大型表或常用表中的某个数据集时。但是,对于一次性事件,最好使用导出 表。 23. 在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果数据量不大,为了缓和系统表的资源,应先create table,然后insert。 24. 如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。 25. 尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写。 26. 使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方案来解决问题,基于集的方法通常更有效。 27. 与临时表一样,游标并不是不可使用。对小型数据集使用 FAST_FORWARD 游标通常要优于其他逐行处理方法,尤其是在必须引用几个表才能获得所需的数据时。在结果集中包括“合计”的例程通常要比使用游标执行的速度快。如果开发时 间允许,基于游标的方法和基于集的方法都可以尝试一下,看哪一种方法的效果更好。 28. 在所有的存储过程和触发器的开始处设置 SET NOCOUNT ON ,在结束时设置 SET NOCOUNT OFF 。无需在执行存储过程和触发器的每个语句后向客户端发送 DONE_IN_PROC 消息。 29. 尽量避免大事务操作,提高系统并发能力。 30. 尽量避免向客户端返回大数据量, 若数据量过大,应该考虑相应需求是否合理。 具体的SQL语句在很多情况下需要结合实际的应用情况来写。 数据库性能优化涉及到很多方面,在数据库开发时可以通过一些基本的优化技巧提高数据库的性能: 1. 原则上为创建的每个表都建立一个主键,主键唯一标识某一行记录,用于强制表的实体完整性。SQL Server 2005 Database Engine 将通过为主键列创建唯一索引来强制数据的唯一性。查询中使用主键时,此索引还可用来对数据进行快速访问。(注意:如果你建立了主键,默认情况下它就是聚集索引) 2. 为每一个外键列建立一个索引,如果确认它是唯一的,就建立唯一索引。当在查询中组合相关表中的数据时,经常在联接条件中使用外键列,索引使 SQL Server 2005 数据库引擎 可以在外键表中快速查找相关数据。 3. 暂时不要为其他列建立索引 4. 当在TSQL中引用对象时,建议使用对象的架构名称限定。(使用dbo.sysdatabases代替sysdatabases)未指定架构可能会导致混淆和意义不明确,还有一个重要原因,当很多连接同时运行同一个存储过程时,如果未指定架构名称,这些连接可能会因为要获取编译锁 (compile lock)而互相阻塞。 5. 使用SET NOCOUNT ON在每个存储过程的开头SET NOCOUNT OFF在结尾。当 SET NOCOUNT 为 ON 时,将不给客户端发送存储过程中的每个语句的 DONE_IN_PROC 信息。当使用 Microsoft SQL Server 提供的实用工具执行查询时,在 Transact-SQL 语句(如 SELECT、INSERT、UPDATE 和 DELETE)结束时将不会在查询结果中显示"n rows affected"。如果存储过程中包含的一些语句并不返回许多实际的数据,则该设置由于大量减少了网络流量,因此可显著提高性能。 补充: 1.当 SET NOCOUNT 为 ON 时,也更新 @@ROWCOUNT 函数。 2. @@ROWCOUNT是返回受上一语句影响的行数,包括找到记录的数目、删除的行数、更新的记录数等,不要认为是返回查找的记录数目,而且 @@ROWCOUNT要紧跟需要判断语句,否则@@ROWCOUNT将返回0。 3. 使用错误处理程序,用来检查 @@ERROR 系统函数的 T-SQL 语句 (IF) 实际上在进程中清除了 @@ERROR 值,无法再捕获除零之外的任何值,必须使用 SET 或 SELECT 立即捕获错误代码。 6. 慎用锁,可以使用NOLOCK提示,它与READUNCOMMITTED是等价的。更简单的做法是在存储过程的开头SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED,结尾READ COMMITTED。 7. 查询仅 仅返回需要的行和列 8. 在适当的时候使用事务,尽量将事务放在一个存储过程中。 9. 尽量少的使用临时表,因为大量使用临时表可能使 tempdb成为瓶颈。可以使用表表达式,包括派生表、CTE、视图和内联表值UDF。 补充:CTE是SQL Server 2005的一项强大而灵活的功能。它使得SQL Server的可读性更强,更易于管理,降低了查询的复杂程度。执行递归查询是CTE最重要也是最强大的功能。 10. 避免使用NOT IN,可以用LEFT OUTER JOIN代替它 11. 如果需要使用动态SQL,sp_executesql更具优势,因为它提供了输入输出接口,并且更有可能重用执行计划,因为你可以更容易的生 成被重复调用的查询字符串。注意有一点声明的参数类型尽量和查询关键字字段类型一致,否则可能导致低的查询效率。 12. 当修改你的代码时,比较前后代码执行的性能,如果发现在CPU、IO上有大的增长,需要检查代码的修改 13. 尽量减少和服务器的交互,可以通过一次返回多结果集来解决。 14. 一般情况下不需要使用INDEX和JOIN提示,因为优化器会选择最优的执行计划。如果统计信息没有更新会影响查询计划的选择。 15. 在本地测试时,可以看一看语句在CPU,IO或执行时间上是否异常。通常利用命令:set statistics io on, set statistics time on , set showplan on 等。 16. 如果用到其他库的Table或View,可以在当前库中建立View来实现跨库操作,最好不要直接使用 “databse.shema.table_name”,因为sp_depends(显示有关数据库对象依赖关系的信息)不能显示出该SP所使用的跨库 table或view,不方便校验。 --执行下面的存储过程显示数据库中依赖于表的数据库对象 EXEC sp_depends @objname = N'user' 17. 尽量避免大事务操作,慎用holdlock子句,提高系统并发能力。 --会话 begin tran --holdlock人为加共享锁 SELECT * from User WITH(HOLDLOCK) where UserID=1 waitfor delay '00:00:10 commit tran --会话 SELECT * from User WITH(HOLDLOCK) where UserID=1 update User set userpw=222222 where UserID=1 --若同时执行上述两个语句,则第二个会话中的select查询可以执行 --而update必须等待第一个会话中的共享锁结束后才能执行,即要等待10秒 18. 尽量避免反复访问同一张或几张表,尤其是数据量较大的表,可以考虑先根据条件提取数据到临时表中,然后再做连接。 19. 尽量避免使用游标,游标的效率较差,因为游标基本上是强制优化器执行固定的计划,并且逐行操作产生大量的开销;如果使用了游标,就要尽量避免在游标循环中再进行表连接的操作。 20. 不要在where子句中进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。 21. 尽量使用exists代替select count(*)来判断是否存在记录 优化器优化exists谓词时优化器支持短路 (short-circuiting)功能。只要找到一行,不需要再扫描其他行就可以确定该表是否包含行了。 count函数只有在统计表中所有行 数时使用, count(1)、count(?)、count(*)哪个效率高的问题,经过测试堆、利用聚集索引、非聚集索引三种情况下这三个的执行效率基本上一样,生成的查询计划是相同的。 22. 注意insert、update操作的数据量,防止与其他应用冲突。如果数据量超过一定的数据页面,系统将会进行锁升级,页级锁会升级成表级 锁。 23. 关于涉及tempdb的使用方面 临时表和表变量被物理的保存在tempdb中,除此之外,SQL Server还为很多隐式操作在tempdb中存储数据。包括:作为查询执行计划的一部分的脱机数据,排序,以及维护行版本(2005)。所以 tempdb可能会成为瓶颈。 1. 尽量少的使用distinct、order by、group by、having、join,因为这些语句会加重tempdb的负担。 2. 避免频繁创建和删除临时表,减少系统表资源的消耗。 3. 在新建临时表时,如果一次性插入数据量很大,那么可以使用select into代替create table,避免log,提高速度;如果数据量不大,为了缓和系统表的资源,建议先create table,然后insert。 4. 如果临时表的数据量较大,需要建立索引,那么应该将创建临时表和建立索引的过程放在单独一个子存储过程中,这样才能保证系统能够很好的使用到该临时表的索引。 5. 如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先truncate table,然后drop table,这样可以避免系统表的较长时间锁定。 6. 慎用大的临时表与其他大表的连接查询和修改,减低系统表负担,因为这种操作会在一条语句中多次使用tempdb的系统表。 24. 关于索引的使用方面 1. 尽可能的使用索引字段作为查询条件,尤其是聚集索引,必要时可以通过index index_name来强制指定索引 2. 避免对大表查询时进行table scan,必要时考虑新建索引。 3. 在使用索引字段作为条件时,如果该索引是联合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用。 4. 要注意索引的维护,周期性重建索引。

MacOS Lion

终于用到Mac的新系统Lion了。。。手势功能得到了增强,其次增加了两个关于APP的新功能,感觉还算可以吧。。。

对了,感觉Lion里面的手势,上下页面反动的方向反过来了,有点不习惯。。。

More secret iPhone codes

转载自:http://www.tuaw.com/2007/07/12/more-secret-iphone-codes/

*3001#12345#* and tap Call. Enter Field Mode.

Field mode reveals many of the inner settings of your iPhone, specifically up-to-date network and cell information.

*#06# Displays your IMEI. No need to tap Call.

IMEI is the unique identifier for your cell phone hardware. Together with your SIM information it identifies you to the provider network.

*777# and tap Call. Account balance for prepaid iPhone.

*225# and tap Call. Bill Balance. (Postpaid only)

*646# and tap Call. Check minutes. (Postpaid only)

These three are pretty self explanatory.

*#21# and tap Call. Setting interrogation for call forwards.

Discover the settings for your call forwarding. You’ll see whether you have voice, data, fax, sms, sync, async, packet access, and pad access call forwarding enabled or disabled.

*#30# and tap Call. Calling line presentation check.

This displays whether you have enabled or disabled the presentation of the calling line, presumably the number of the party placing the call.

*#76# and tap Call. Check whether the connected line presentation is enabled or not.

State whether the connected line presentation is enabled or disabled. Presumably similar to the calling line presentation.

*#43# and tap Call. Determine if call waiting is enabled.

Displays call waiting status for voice, data, fax, sms, sync data, async data, packet access and pad access. Each item is either enabled or disabled.

*#61# and tap Call. Check the number for unanswered calls.

Show the number for voice call forwarding when a call is unanswered. Also show the options for data, fax, sms, sync, async, packet access and pad access.

*#62# and tap Call. Check the number for call forwarding if no service is available.

Just like the previous, except for no-service rather than no-answer situations.

*#67# and tap Call. Check the number for call forwarding when the iPhone is busy.

And again, but for when the iPhone is busy.

*#33# and tap Call. Check for call control bars.

Check all the usual suspects (voice, data, fax, sms, etc) to see whether barring is enabled or disabled for outgoing.

关于后台命名

二号机,今天我在调整后台的时候看到一个test,我以为是没用的直接就删了,删了以后发现首页上面的导航功能没了,我一下子郁闷了。最后在我的不懈努力下虽然解决了,但是这个故事告诉我们命名是需要规范的。。。

Macintosh & Mac Book Pro

我的MBP终于来了,现在每天面对的Macintosh的系统让我感触颇深。

首先是MBP这个机子本身,做工是没有话说的银银的、薄薄的,亮亮的,虽然网上品论说散热有问题,但是我用下来感觉还行,哪怕是上了虚拟机也是能接受的。。。

其次是MacOS X,我现在用的是10.6,这个月说是会出10.7Lion,据说是增加了好多触摸板的手势和其他好多功能,但是即便是现在我也感觉到了苹果工程师的强大。我相当佩服MacOS在手势上的设计从一根手指到四根手指敏锐的感应度相当的高,而且触摸板很大感觉用鼠标反而没有用触摸板来的舒服了,因为鼠标的手势太少了。

不过MacOS的优点也就到这里结束了,从Windows转到MacOS肯定会感觉到相当多的不适应,而且对于一点UNIX/Linux方面的技术都没接触过的人而言可能会感到迷茫。

Windows和MacOS的不同:
1.MacOS、Linux、Unix没有C盘D盘的概念,这里的分区是以根目录(/)为最基本的根,其次所有的文件系统都是以挂载的形式读写,如果需要更加详细了解这个分区的概念,可以参考一些Linux的入门教学。

2.在MacOS中没有Crtl+X的剪贴功能,虽然MacOS保留了这个剪贴的概念,但是它只能在文字编辑的时候用,不能对文件进行剪贴。如果要实现对文件的剪贴功能,可以使用第三方或者在使用鼠标的时候对鼠标行为进行设定。

3.由于键盘的不同,MacOS和Windows在快捷键上面有相当大的分歧,主要可以参考官方给出来的快捷键列表。值得一提的是Mac中的Command+Tab只能切换程序之前,比如QQ有两个对话框需要切换,那么需要使用Command+`。

4.Windows中常用的工具,在MacOS中虽然也能找到一些相应的替代品,但是肯定是会有很多的不适应,当然如果肯付钱买就是另外一回事情了。主要的有字典、媒体播放器、下载工具、输入法、聊天工具、Office等等。

字典:MacOS中自带有字典工具,主要的缺点是字典太少,解决这个问题可以有几个方法:1.出钱买;2.找转换工具转换其他Windows下可用的字典工具的字典库加入MacOS中。

音乐播放器:首先可以用MacOS自带的iTunes播放器,如果像我一样不喜欢iTunes可以使用VLC。我之所以不喜欢iTunes是因为每次加入音乐的时候都要在它的Library加入一次,不能直接读取目标文件夹来播放。其次VLC有个很二很致命的弱点,它不能记录播放列表也就是Playerlist,解决这个问题的办法是做好Playerlist以后保存list,然后下次直接对list进行打开而不是对VLC进行打开。

视频媒体问题:Rmvb和wmv格式的视频文件在MacOS中也是不能播放的,可以下载Flip4mac和realplay进行解决。

下载工具:有一个叫iDown的,可以读取迅雷之类的路径,可以试试这个。我还没尝试过所以不好做什么评语,这里只是介绍给大家。

输入法:很幸运的是2011.7.1开始搜狗推出了Mac版输入法,我现在正用着呢,感觉不错。

聊天工具:无论是QQ还是MSN都有Mac版的,MSN大家用的不多,而且用下来问题不大不用多说,关键是QQ做的很二,功能只有Windows底下的30%左右。当然MacOS也自带了iChat工具可以直接对jabber设定甚至登陆QQ等等,但是除了ichat自带默认能登陆的,其他DIY的一律不推荐,不安全,而且容易掉线。

Office:在Office方面,首先可以使用OpenOffice,这个是没话说的,因为国人用的不多。关键要说的是微软的Office,也就是Office for Mac,它提供了Word、PowerPoint、Excel三个,主要问题是出了界面完全不同,操作的习惯有很大差别意外,启动很慢、Word中自动生成的目录和更新目录功能不好用,或者是我还没研究出来怎么用,PowerPoint和Excel因为还没使用到所以不做评论。

SVN:开发中要使用到的Subversion客户端工具,可以使用svnX这个GUI工具,或者直接在Terminal敲命令。

有些朋友喜欢用notepad++,MacOS中其实不需要,因为它有个强大的Terminal…

5.在Windows中,对着对话框右上角的红叉按一下,无论是程序还是软件都会关闭,但是在MacOS中不是的。MacOS的坐上角也有个红叉,但是那只是最小化,要关闭的话要使用Command+Q快捷键才行,这个大家要注意一下。另外在Dock上面,凡是启用这的程序下面有个小亮点可以留一下。

6.Mac的窗口有一点不太人性化,推拉大小的时候只能在右下角拖拉,而且人家Windows7开始就能迅速半屏全屏它也没,这个对于我这种用惯快速半屏全屏的人来说是一个痛,估计能有什么第三方来解决这个问题,不过我还没找到。

7.防火墙和杀毒软件的问题,首先在Mac的系统属性(类似与Windows的控制面板)中,可以启用它自带的防火墙。其次由于MacOS虽然不是Linux,但是也是类UNIX的系统,流行的病毒主要是针对Windows,这点可以不用太在意,裸奔问题也不大。当然在意和人可以和我一样安装个iAntiVirus或者Clam antivirus,再或者彻底一点专业一点多来个Rootkit Hunter、Tripwire,再做Cron定期检测系统。

8.最最致命的问题还是在于和Windows的交流上非常差,第一TXT文件过来都是乱码,需要对TextEdit的属性进行设定,让它以Windows的模式打开。第二是NTFS格式的外接移动硬盘在MacOS10.6的时候只可读不可写,MacOS10.7估计也是一样的,解决方法是安装两个东西:MacFUSE、Tuxera NTFS。增加NTFS格式的可读功能除了可以安装程序意外,也可以修改UUID来解决,因为我修改了没有成功,所以就不介绍了。