linux 复习笔记 – VIM 使用

blob.png

多窗口功能

想象两个情况: 

• 当我有一个档案非常的大,我查阅到后面的数据时,想要『对照』前面的数据, 是否需要使用 [ctrl]
+f 与 [ctrl]+b 来跑前跑后查阅? 

• 我有两个需要对照着看的档案,不想使用前一小节提到的多档案编辑功能;
这样的情况下,开一个 vim 里头有两个窗口的环境,就有需要啦!那么如何开启新窗口呢? 很简单啊!
在指令列模式输入:『:sp {filename}』,那个 filename 可有可无, 如果想要在新窗口启动另一个档案,
就加入档名,否则仅输入 :sp 时, 出现的则是同一个档案在两个窗口间!例如鸟哥使用 vim hosts 后,
再以 :sp /etc/hosts , 

结果出现如下图示:

blob.png

怎样?帅吧!两个档案同时在一个屏幕上面显示,您还可以利用『[ctrl]+w+j』及『[ctrl]+w+k』 在两个
窗口之间移动呢!这样的话,复制啊、查阅啊等等的,就变的很简单啰~ 指令的功能有很多,不过,您只
要记得这几个就好了:

blob.png

vim 环境设定
有没有发现,

如果我们以 vim 软件来搜寻一个档案内部的某个字符串时,

这个字符串会被反白, 

而下次
我们再次以 vim 编辑这个档案时,

该搜寻的字符串还是存在呢!

甚至于, 编辑其它档案时,如果其它档
案也存在这个字符串,哇!!

竟然还是主动反白耶! 

另外,当我们重复编辑同一个档案时,当第二次进入
该档案时, 光标竟然就在上次离开的那一行上头呢!

真是好方便啊~但是,怎么会这样呢? 

这是因为我们的 vim 会主动的将您曾经做过的行为登录下来,好让您下次可以轻松的作业啊! 

那个记录
动作的档案就是: ~/.viminfo 这个档案啦!

每个人的家目录都应该会存在这个档案才对~这个档案是自
动产生的, 您不必自行建立。

而你在 vim 里头所做过的动作,就可以在这个档案内部查询到啰~ ^_^
此外,某些 distributions 的 vim 当中,利用搜寻时,他并不会显示反白, 有些 distributions 则会
主动的帮您进行缩排的行为 (所谓的缩排, 就是当您按下 Enter 编辑新的一行时,光标不会在行首,而
是在与上一行的第一个非空格符处对齐!)。 

这些其实都可以进行设定的,那就是 vim 的环境设定啰~ vim
的环境设定参数有很多,如果您想要知道目前的设定值,可以在一般模式时输入:『 :set all 』 来查阅,
不过…..设定项目实在太多了~所以,鸟哥在这里仅列出一些平时比较常用的一些简单的设定值, 提供
给您参考啊:

blob.png

blob.png

blob.png

linux 复习笔记 – zip&unzip

ZIP


选项

-A:调整可执行的自动解压缩文件;
-b<工作目录>:指定暂时存放文件的目录;
-c:替每个被压缩的文件加上注释;-d:从压缩文件内删除指定的文件;
-D:压缩文件内不建立目录名称;-f:此参数的效果和指定“-u”参数类似,但不仅更新既有文件,如果某些文件原本不存在于压缩文件内,使用本参数会一并将其加入压缩文件中;
-F:尝试修复已损坏的压缩文件;
-g:将文件压缩后附加在已有的压缩文件之后,而非另行建立新的压缩文件;
-h:在线帮助;
-i<范本样式>:只压缩符合条件的文件;
-j:只保存文件名称及其内容,而不存放任何目录名称;
-J:删除压缩文件前面不必要的数据;
-k:使用MS-DOS兼容格式的文件名称;-l:压缩文件时,把LF字符置换成LF+CR字符;
-ll:压缩文件时,把LF+cp字符置换成LF字符;
-L:显示版权信息;
-m:将文件压缩并加入压缩文件后,删除原始文件,即把文件移到压缩文件中;
-n<字尾字符串>:不压缩具有特定字尾字符串的文件;
-o:以压缩文件内拥有最新更改时间的文件为准,将压缩文件的更改时间设成和该文件相同;
-q:不显示指令执行过程;
-r:递归处理,将指定目录下的所有文件和子目录一并处理;
-S:包含系统和隐藏文件;
-t<日期时间>:把压缩文件的日期设成指定的日期;
-T:检查备份文件内的每个文件是否正确无误;
-u:更换较新的文件到压缩文件内;
-v:显示指令执行过程或显示版本信息;
-V:保存VMS操作系统的文件属性;
-w:在文件名称里假如版本编号,本参数仅在VMS操作系统下有效;
-x<范本样式>:压缩时排除符合条件的文件;
-X:不保存额外的文件属性;
-y:直接保存符号连接,而非该链接所指向的文件,本参数仅在UNIX之类的系统下有效;
-z:替压缩文件加上注释;
-$:保存第一个被压缩文件所在磁盘的卷册名称;
-<压缩效率>:压缩效率是一个介于1~9的数值。

参数

  • zip压缩包:指定要创建的zip压缩包;

  • 文件列表:指定要压缩的文件列表。

实例

/home/Blinux/html/这个目录下所有文件和文件夹打包为当前目录下的html.zip:

zip -q -r html.zip /home/Blinux/html

上面的命令操作是将绝对地址的文件及文件夹进行压缩,以下给出压缩相对路径目录,比如目前在Bliux这个目录下,执行以下操作可以达到以上同样的效果:

zip -q -r html.zip html

比如现在我的html目录下,我操作的zip压缩命令是:

zip -q -r html.zip *

UNZIP


-c:将解压缩的结果显示到屏幕上,并对字符做适当的转换;-f:更新现有的文件;-l:显示压缩文件内所包含的文件;
-p:与-c参数类似,会将解压缩的结果显示到屏幕上,但不会执行任何的转换;
-t:检查压缩文件是否正确;
-u:与-f参数类似,但是除了更新现有的文件外,也会将压缩文件中的其他文件解压缩到目录中;
-v:执行时显示详细的信息;
-z:仅显示压缩文件的备注文字;-a:对文本文件进行必要的字符转换;
-b:不要对文本文件进行字符转换;
-C:压缩文件中的文件名称区分大小写;
-j:不处理压缩文件中原有的目录路径;
-L:将压缩文件中的全部文件名改为小写;
-M:将输出结果送到more程序处理;
-n:解压缩时不要覆盖原有的文件;
-o:不必先询问用户,unzip执行后覆盖原有的文件;
-P<密码>:使用zip的密码选项;
-q:执行时不显示任何信息;-s:将文件名中的空白字符转换为底线字符;
-V:保留VMS的文件版本信息;
-X:解压缩时同时回存文件原来的UID/GID;-d<目录>:指定文件解压缩后所要存储的目录;
-x<文件>:指定不要处理.zip压缩文件中的哪些文件;
-Z:unzip-Z等于执行zipinfo指令。

参数

压缩包:指定要解压的“.zip”压缩包。

实例

将压缩文件text.zip在当前目录下解压缩。

unzip test.zip

将压缩文件text.zip在指定目录/tmp下解压缩,如果已有相同的文件存在,要求unzip命令不覆盖原先的文件。

unzip -n test.zip -d /tmp

查看压缩文件目录,但不解压。

unzip -v test.zip

将压缩文件test.zip在指定目录/tmp下解压缩,如果已有相同的文件存在,要求unzip命令覆盖原先的文件。

unzip -o test.zip -d tmp/

linux 复习笔记 – 用户与用户组

blob.png

blob.png

第一个属性代表这个档案是『目录、档案或连结文件等等』: 

当为[ d ]则是目录,例如上表的第 11 行; 

当为[ – ]则是档案,例如上表的第 5 行;

若是[ l ]则表示为连结档(link file);

若是[ b ]则表示为装置文件里面的可供储存的接口设备;

若是[ c ]则表示为装置文件里面的串行端口设备,例如键盘、鼠标。

需要特别留意的是 x 这个标号! 若文件名为一个目录的时候,例如上表中的 .ssh 这
个目录

blob.png

可以看到这是一个目录,而且只有 root 可以读写与执行。但是若为底下的样式时,请问非 root 的其它人是否可以进入该目录呢?

blob.png

咦!似乎好像是可以喔!因为有可读[ r ]存在嘛!『错!』答案是非 root 这个账号的其它使用者均不可进入 .ssh 这个目录,为什么呢? 

因为 x 与 目录 的关系相当的重要, 如果在该目录底下不能执行任何指令的话,那么自然也就无法进入了。

如何改变档案权限

chgrp :改变档案所属群组

chown :改变档案所属人

blob.png

chmod :改变档案的属性、 SUID、等等的特性

r:4
w:2
x:1

blob.png

blob.png

blob.png

blob.png

blob.pngblob.png

blob.png

blob.png

php 获取月份最后一天

<?php
    echo date("t",strtotime('2016-02'));
?>

常用方法

<?php
echo strtotime("now"), "\n";
echo strtotime("10 September 2000"), "\n";
echo strtotime("+1 day"), "\n";
echo strtotime("+1 week"), "\n";
echo strtotime("+1 week 2 days 4 hours 2 seconds"), "\n";
echo strtotime("next Thursday"), "\n";
echo strtotime("last Monday"), "\n";
?>

php生成的csv, 无法完整显示带前导0的数字

PHP生成csv文件时,如果数字的第一位为0的话,显示时则不会显示第一个0

可以在php中做特殊处理,使得生成的csv在显示时能显示出第一个0

有两种方法可以实现:

1、给数字加上引号,并且在引号前面再加上个等号,如数字0555,,则生成时为="0555"

2、在数字前面加上制表符,如是数字0555,则生成时为\t0555

代码如下:

$arr    = array (  
    array ('111', 2222, '0555'),  
    array ('222', 3333, '0666')  
);  
$fp    = fopen('t.csv', 'w');  
foreach ($arr as $row) {  
    fputcsv($fp, array_map('h', $row));  
}  
fclose($fp);  
  
function h($v) {  
    if (($v{0} == '0') && is_numeric($v)) {  
        $v    = '="' . $v . '"';    //第一种方式  
        //$v   = "\t{$v}";  //第二种方式  
    }  
    return $v;  
}

Linux下的ip命令,ifconfig已经过时了

Linux的ip命令和ifconfig类似,但前者功能更强大,并旨在取代后者。使用ip命令,只需一个命令,你就能很轻松地执行一些网络管理任务。ifconfig是net-tools中已被废弃使用的一个命令,许多年前就已经没有维护了。iproute2套件里提供了许多增强功能的命令,ip命令即是其中之一。

CentOS的ifconfig, route以及ip指令的实战应用 http://www.linuxidc.com/Linux/2013-05/83956.htm

CentOS安装后ifconfig 无法显示网卡 http://www.linuxidc.com/Linux/2013-04/82573.htm

CentOS的ifconfig, route以及ip指令的实战应用 http://www.linuxidc.com/Linux/2013-05/83956.htm

ifconfig: command not found  http://www.linuxidc.com/Linux/2012-07/64703.htm

CentOS 6.2下ifconfig输出网口和ip http://www.linuxidc.com/Linux/2012-06/63672.htm

要安装ip,请点击这里下载iproute2套装工具 。不过,大多数Linux发行版已经预装了iproute2工具。

你也可以使用git命令来下载最新源代码来编译:

  1. $ git clone https://kernel.googlesource.com/pub/scm/linux/kernel/git/shemminger/iproute2.git

设置和删除Ip地址

要给你的机器设置一个IP地址,可以使用下列ip命令:

  1. $ sudo ip addr add 192.168.0.193/24 dev wlan0

请注意IP地址要有一个后缀,比如/24。这种用法用于在无类域内路由选择(CIDR)中来显示所用的子网掩码。在这个例子中,子网掩码是255.255.255.0。

在你按照上述方式设置好IP地址后,需要查看是否已经生效。

  1. $ ip addr show wlan0

你也可以使用相同的方式来删除IP地址,只需用del代替add。

  1. $ sudo ip addr del192.168.0.193/24 dev wlan0

列出路由表条目

ip命令的路由对象的参数还可以帮助你查看网络中的路由数据,并设置你的路由表。第一个条目是默认的路由条目,你可以随意改动它。

在这个例子中,有几个路由条目。这个结果显示有几个设备通过不同的网络接口连接起来。它们包括WIFI、以太网和一个点对点连接。

  1. $ ip route show

假设现在你有一个IP地址,你需要知道路由包从哪里来。可以使用下面的路由选项(译注:列出了路由所使用的接口等):

  1. $ ip route get10.42.0.47

Linux-关闭笔记本盖不休眠

systemd 处理某些电源相关的 ACPI事件,可以通过从 /etc/system/logind.conf以下选项进行配置:

HandlePowerKey按下电源键后的行为,默认power off

HandleSleepKey 按下挂起键后的行为,默认suspend

HandleHibernateKey 按下休眠键后的行为,默认hibernate

HandleLidSwitch 合上笔记本盖后的行为,默认suspend

触发的行为可以有

ignore、power off、reboot、halt、suspend、hibernate、hybrid-sleep、lock 或 exec。

如果要合盖不休眠只需要把HandleLidSwitch选项设置为如下即可:

HandleLidSwitch=lock

注意:设置完成保存后运行下列命令才生效。

systemctl restart systemd-logind

Angular

Angular的八大件。Angular主要有8个东西构成,包括:

  • 模块 (module)

  • 组件 (component)

  • 模板 (template)

  • 元数据 (metadata)

  • 数据绑定 (data binding)

  • 指令 (directive)

  • 服务 (service)

  • 依赖注入 (dependency injection)

这八大件就好比孙悟空身上的毛,拔下来一吹,能变出各种东西来。所以啊,只要你吃透了这老北京八大件,那做一个客户端应用简直就是分分钟的事儿。

模板基本定义了你的应用长啥样,长得好不好看得有人看着,组件就负责管理这些模板。长得好看没用那不就成了花瓶了么,所以还需要服务来给应用添加一些逻辑,这些东西东一块西一块的乱七八糟还真不行,我们还需要模块来打包所有的组件、服务等等。所以说,模块就是用来打包的。一个应用程序有很多模块打的包,一层一层的,最开始那个就叫做根模块。我们通过引诱(其实是引导吧)根模块来启动程序。

我偷偷从官网偷了一张照片来给大家感受一下这八大件是怎么互相配合的。

  

那下面就浅显地介绍一下这八大件。

模块 (Module)

刚才提到了根模块,是用来启动程序的。没有根模块,再好的程序也跑不起来。所以模块很重要很重要。Angular的应用,都是模块化的。每个feature特性都有自己的子模块,无论是子模块还是根模块定义的结构都差不多。我们可以把模块看成一个行李箱,里面装满了各种东西。包括declaration、imports、providers等。declaration用来放各种小零件,包括组件、指令、管道等。imports是导入其他的模块。providers用来盛放各种service。for一个example,一个module大概长这个样子。关于Module的细节,下一篇Angular的文章我会详细说哒。

  

组件 (Component) 元数据 (Metadata) 模板 (Template)

这仨可以一起说。

模板就是HTML,就是你告诉Angular,喂喂喂,这儿你给我加个按钮,那儿你给我来个日历就是这样。除了<h1> <p>等等这些常见的html元素,我们还可以加自定义的元素在模板里面。

组件负责让模板看起来没那么无聊。比如你在模板里面定义了一个按钮,那你按了之后发生了什么啊?或者你定义了一个input box,你输入你的名字后会发生什么啊?这就需要Component来定义。

那每个Component都不一样,我们怎么区分呢?其实应该说Angular怎么识别呢?就是靠这个叫做元数据的东西。元数据会定义一些配置细节,告诉Angular:嘿Angular,如果你想把这个东西给大家看,那你得先去做ABCDEFG这几件事儿。Angular按照元数据的指示,根据Template的样子最后创建视图。

数据绑定 (Data Binding)

如果没有任何框架,我们自己写数据绑定,那简直就是人间地狱啊,噩梦啊。之前我们可怜的前端程序员都是用jQuery,我们要纯手工打造各种数据更新,UI更新,经常犯错,bug一堆堆,debug简直就是家常便饭。后来越来越多的框架都有数据绑定了,无论是单向的双向的还是五花板门乱七八糟项的,都帮我们可怜的前端程序员省去了很多时间。这样我们就可以早早下班回家老婆孩子热炕头了。

Angular2比Angular1更好滴实现了数据绑定。一共有四种吧:

  1. {{someString}}这个叫插值绑定,从Component到DOM,之前在Angular1里面也有

  2. [someThing] 这个叫属性绑定,也是从Component到DOM

  3. (event)这个是事件绑定,从DOM到Component

  4. 最后一个就是把上面这两个结合在一起[(ng…)] 双向绑定

  

除了这四种现在在各大框架中都十分普遍的绑定方式外,Angular2里面还有一种爸爸对儿子的@input绑定和儿子对爸爸的@output绑定。这种方式让爸爸跟儿子毫无代沟,交流起来丝毫不费力。

指令 (directive)

指令跟组件(Component)非常类似,其实组件就相当于一个指令。指令地位崇高,包括结构型指令和属性指令。

结构型我们在Angular1里面也经常用啊,就是现在语法不太一样了,比如ngfor, ngIf等等,都是结构型指令。这些一般是不会改变任何元素的行为啦,外观啦等等。相反,属性型就非要改外观或者行为。

服务(Service)

以前呐,总听说中国服务业不发达,我回家一看,这挺发达的啊,到处灯红酒绿的。人想活的好啊,还得靠服务业,不是大保健那种服务啦。

  

应用程序中的服务无处不在无孔不入,哪儿都有它。上面介绍的组件里面有一些变量,有些用户输入的变量啦,用户的选择啦,这些数据都乖乖地待在前端呢,不直接跟服务器对话。要不你用户爱输入什么输入什么,爱上传什么上传什么,服务器不就炸裂了么?组件要与服务(service)直接沟通。这样服务里面就可以加一些验证逻辑,比如你想下载小黄片什么的,服务可以阻止你(其实没有这种服务)。服务就像大宅子里面的大管家,所有的琐事儿都是服务来管。大管家希望每一个组件尽量精简,其余的细节内容都交给服务托管。那组件中如何使用这些服务呢?就靠下面要介绍的依赖注入。

依赖注入(Dependency Injection)

Angular通过依赖注入让组件可以使用服务。Angular创建一个组件的时候,首先你得跟上级领导请求,喂,领导啊,我这个组件需要这些服务,领导说,那好吧,那给你个注射器(injector)你用去吧。就像这样:

constructor( private service: MyService)

这个注射器啊会存放以前创建的那个服务,上面这行代码就是用service来存放之前创建好的MyService。那有些同学就要问了,你啥时候创建MyService的,我咋不知道?哦对,那如果这个服务还没有被创建的话,聪明的注射器同学就会先创建一个MyService服务实例,然后把这个服务跟Angular讲。这就是依赖注入啦。

  

mysql探究之null与not null

相信很多用了MySQL很久的人,对这两个字段属性的概念还不是很清楚,一般会有以下疑问:

1、我字段类型是not null,为什么我可以插入空值

2、为毛not null的效率比null高

3、判断字段不为空的时候,到底要  select * from table where column <> '' 还是要用 select * from table where column is not null 呢。

带着上面几个疑问,我们来深入研究一下null 和 not null 到底有什么不一样。

首先,我们要搞清楚“空值” 和 “NULL” 的概念:

1、空值是不占用空间的

2、mysql中的NULL其实是占用空间的,下面是来自于MYSQL官方的解释

“NULL columns require additional space in the row to record whether their values are NULL. For MyISAM tables, each NULL column takes one bit extra, rounded up to the nearest byte.”

打个比方来说,你有一个杯子,空值代表杯子是真空的,NULL代表杯子中装满了空气,虽然杯子看起来都是空的,但是区别是很大的。

搞清楚“空值”和“NULL”的概念之后,问题基本就明了了,我们搞个例子测试一下:

CREATE TABLE  `test` (  
 `col1` VARCHAR( 10 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,  
 `col2` VARCHAR( 10 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL  
) ENGINE = MYISAM ;

插入数据:

INSERT INTO `test` VALUES (null,1);

mysql发生错误:Column 'col1' cannot be null   

再来一条

INSERT INTO `test` VALUES ('',1);

成功插入。

可见,NOT NULL 的字段是不能插入“NULL”的,只能插入“空值”,上面的问题1也就有答案了。

对于问题2,上面我们已经说过了,NULL 其实并不是空值,而是要占用空间,所以mysql在进行比较的时候,NULL 会参与字段比较,所以对效率有一部分影响。

而且B树索引时不会存储NULL值的,所以如果索引的字段可以为NULL,索引的效率会下降很多。

我们再向test的表中插入几条数据:

INSERT INTO `test` VALUES ('', NULL);  
INSERT INTO `test` VALUES ('1', '2');

现在表中数据:

现在根据需求,我要统计test表中col1不为空的所有数据,我是该用“<> ''” 还是 “IS NOT NULL” 呢,让我们来看一下结果的区别。

SELECT * FROM `test` WHERE col1 IS NOT NULL

SELECT * FROM `test` WHERE col1 <> ''


可以看到,结果迥然不同,所以我们一定要根据业务需求,搞清楚到底是要用那种搜索条件。

提高mysql千万级大数据SQL查询优化30条经验(Mysql索引优化注意)

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 也要慎用(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 '李%'若要提高效率,可以考虑全文检索。

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 name like 'abc%'

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查询可能不会去利用索引,如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。

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.尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。