2013年6月26日星期三

【转】XShell下乱码的解决方法

首先检查系统的language设置的是否是中文。
在终端下输入命令∶
# echo $LANG
若不是,则需要修改环境变量。修改环境变量有多种方法,简单总结三种比较常用的∶
1>只针对当前终端的修改,对其他用户没有影响
    在命令行下输入∶
    # export LANG=ja_JP.UTF-8
    这种修改只对当前终端有效,终端退出后即结束。若想要查看系统支持的语言和字符集,可以用命令
    # locale -a
2>针对当前用户的修改,修改当前用户的bash配置文件。当用户一登陆即export进LANG变量
    先进入当前用户的home目录,如root用户的home目录是/root/,其他用户的home目录一般是/home/username/
    # ls -a
    可以看到.bash_profile这个隐藏文件,在终端下输入一下命令∶
    # echo “export LANG=ja_JP.UTF-8” >> .bash_profile
    此命令的作用是吧echo命令的输出重定向输出到.bash_profile的末尾
3>针对所有用户的修改
    编辑/etc/sysconfig/i18n这个文件,i18n是internationalization的缩写,表示i和n之间有18个字母,本意是 指软件的国际化。i18n支持多种语言,但同一时间只能是英文和一种选定的语言,例如英文+中文、英文+日文等等。
    修改LANG变量的值即可
    以 上只是修改了系统的字符编码。但是即便编码正确,在xshell下也可能会乱码。因为xshell也有编码的设置。在xshell的工具栏上有一个 encoding的按钮,单击这个按钮可以选择编码。如果是日文乱码,一般可以选择Unicode(UTF-8)、Japanese(EUC)、 Japanese(shift-JIS)这三种,具体是哪一种能够正确的显示并不乱码跟要显示的文件所用的编码有关。
    当然,除了第一种方式可以马上使设置生效,第二种方式和第三种方式需要重启shell。

摘自:http://www.cnblogs.com/dongzhiquan/archive/2011/03/20/1994499.html

【转】VirtualBox在NAT下的端口映射

在win7下装的virualbox,虚拟系统为ubuntu下,网络设置为NAT,在ubuntu先安装tomcat,但是web应用程序由于框架的限制对firefox有点不兼容,只能用ie。但是在NAT下无法在局域网中访问ubuntu,只好采取端口映射。

 

1查看设备名称

  在VirtualBox菜单栏,单开“控制”--》“日志菜单”,点击查找写入关键字“NAT”查找类似以下内容

 

Java代码  收藏代码
  1. 00:00:00.688 [/Devices/e1000/0/LUN#0/] (level 4)  
  2. 00:00:00.688   Driver <string>  = "NAT" (cb=4)  

 

       /Devices/e1000/0/LUN#0/设备标识。

2 在cmd下执行以下命令,可以放在bat下执行

 

Java代码  收藏代码
  1. VBoxManage.exe  setextradata "ubuntu" "VBoxInternal/Devices/e1000/0/LUN#0/Config/http/Protocol" TCP  
  2.   
  3. VBoxManage.exe  setextradata "ubuntu" "VBoxInternal/Devices/e1000/0/LUN#0/Config/http/GuestPort" 8080  
  4.   
  5. VBoxManage.exe  setextradata "ubuntu" "VBoxInternal/Devices/e1000/0/LUN#0/Config/http/HostPort" 8080  
  6.   
  7.   
  8. VBoxManage.exe  setextradata "ubuntu" "VBoxInternal/Devices/e1000/0/LUN#0/Config/shell/Protocol" TCP  
  9.   
  10. VBoxManage.exe  setextradata "ubuntu" "VBoxInternal/Devices/e1000/0/LUN#0/Config/shell/GuestPort" 22  
  11.   
  12. VBoxManage.exe  setextradata "ubuntu" "VBoxInternal/Devices/e1000/0/LUN#0/Config/shell/HostPort" 22  

 上面对ssh端口和tomcat的端口(这里用的是8080)进行了映射,其中 VBoxManage.exe 安装在virtualBox目录下,

后面“ubuntu”是虚拟系统的名字,后面是设备标识,对照步骤1应该可以明白,config后面一个名字例如http和shell

可以任意取,GuestPort是虚拟机中所启动服务的端口,HostPost是主机上的映射端口。执行完毕之后,重新启动

虚拟机,就可以了。注意是启动虚拟机不是重启虚拟的ubuntu系统。


摘自:http://jiajw0426.iteye.com/blog/812647

2013年6月24日星期一

【转】 Windows中VirtualBox虚拟机实现桥接方式(Bridged Adapter)

VirtualBox 装好之后默认的网络是NAT模式,但这种模式中虚拟机配置的IP和主机的不再同一网段内,无法获得和主机一样的局域网地位,更不可能从主机用远程桌面携带硬盘的方式远程控制。而最简便的方法就是虚拟机使用桥接的网络方式。

海波很久没有写点像样的东西,写这篇算冲个数吧,也没什么技术含 量,新手入门级的。今天海波第一次使用 VirtualBox 这款虚拟机软件,用的还是绿色版的(Portable-VirtualBox),如有需要可以搜索之或者在文末下载。网上有好多 Linux 下的桥接教程,Windows下的不多哦。

首先说一下我的环境,主机系统是 Windows 7 旗舰版;VirtualBox 虚拟机是 3.0.4 r50677 的绿色版本 Portable-VirtualBox,各个版本的设置应该是大同小异吧;虚拟机安装 Windows XP SP3。
http://www.renhaibo.com/archives/136.html

问题及解决过程如下(虚拟机安装操作系统省略)

1.在刚装好的XP虚拟机的网络设置界面如下图,当链接方式为"Bridged Adapter"的时候,下面的"名称"显示"未指定",而且在下面有错误提示如"发现无效设置"和"在 网络:网络连接 1 页,未指定要bridged的主机网络界面"。
http://www.renhaibo.com/archives/136.html

2.这是因为 Windows 7 系统中没有安装 VirtualBox 的桥接服务驱动(也可能是我用绿色版本的原因),接下来将要安装驱动。

3.打开本地连接的属性界面,如下图
http://www.renhaibo.com/archives/136.html

4.选择"安装(N)...",进入如下图界面
http://www.renhaibo.com/archives/136.html

5.选择"服务",点击"添加(A)..."按钮,进入如下界面
http://www.renhaibo.com/archives/136.html

6.点击"从磁盘安装(H)...",出现可以浏览目录的界面
http://www.renhaibo.com/archives/136.html

7.点击"浏览(B)...",并找到 VirtualBox 的安装目录
http://www.renhaibo.com/archives/136.html

8.进入目录后选择文件夹"app32"(因为我用的是32的系统,如果您用64位系统的话估计得选择"app64"文件夹),然后是驱动目录 "drivers",再就是网络目录"network",再往后您就要根据您的情况选择了,不清楚的话也可以挨个试试,这里我选的是"netflt"中的 "VBoxNetFlt_m"。过程图解如下6张图。
http://www.renhaibo.com/archives/136.html
http://www.renhaibo.com/archives/136.html
http://www.renhaibo.com/archives/136.html
http://www.renhaibo.com/archives/136.html
http://www.renhaibo.com/archives/136.html

9.点"打开"后一路点"确定"就会安装成功,中间安装过程可能需要等待一会儿,如下3张图片
http://www.renhaibo.com/archives/136.html
http://www.renhaibo.com/archives/136.html
http://www.renhaibo.com/archives/136.html

10.至此,桥接服务已经安装好了,可以选择桥接的网络模式了
http://www.renhaibo.com/archives/136.html

这样 VirtualBox 虚拟机中系统和宿主主机中的系统在网络中的地位是平等的,就可以用远程桌面的方式去访问虚拟机了,这样我觉得要比直接在虚拟机中操作要好,只是我个人的感觉而已,用 VMware 海波也是这么干的,是不是有点变态啊。

关于远程桌面的文章可以参考:远程桌面之服务器端的设置》、《远程桌面之网络环境的配置》和《远程桌面之客户端的设置》。

附件(绿色版VirtualBox下载地址):Portable-VirtualBox(请下载后查杀毒)

转载请注明,转自:RenHaibo.com
本文链接地址:http://www.renhaibo.com/archives/136.html

【转】VitualBox网络连接形式

VirtualBox的提供了四种网络接入模式,它们分别是:

1、NAT    网络地址转换模式(NAT,Network Address Translation)

2、Bridged Adapter    桥接模式

3、Internal    内部网络模式

4、Host-only Adapter  主机模式

 

下面我们分别对这四种网络模式进行分析解释:

第一种:NAT模式

NAT模式是最简单的实现虚拟机上网的方式,你可以这样理解:Vhost访问网络的所有数据都是由主机提供的,vhost并不真实存在于网络中,主机与网络中的任何机器都不能查看和访问到Vhost的存在。

 

虚拟机与主机关系:只能单向访问,虚拟机可以通过网络访问到主机,主机无法通过网络访问到虚拟机。

 

虚拟机与网络中其他主机的关系:只能单向访问,虚拟机可以访问到网络中其他主机,其他主机不能通过网络访问到虚拟机。

 

虚拟机与虚拟机之间的关系:相互不能访问,虚拟机与虚拟机各自完全独立,相互间无法通过网络访问彼此。

 

IP:10.0.2.15

网关:10.0.2.2

DNS:10.0.2.3

 

一 台虚拟机的多个网卡可以被设定使用 NAT, 第一个网卡连接了到专用网 10.0.2.0,第二个网卡连接到专用网络 10.0.3.0,等等。默认得到的客户端ip(IP Address)是10.0.2.15,网关(Gateway)是10.0.2.2,域名服务器(DNS)是10.0.2.3,可以手动参考这个进行修 改。

 

NAT方案优缺点:

笔记本已插网线时: 虚拟机可以访问主机,虚拟机可以访问互联网,在做了端口映射后(最后有说明),主机可以访问虚拟机上的服务(如数据库)。

 

笔记本没插网线时: 主机的“本地连接”有红叉的,虚拟机可以访问主机,虚拟机不可以访问互联网,在做了端口映射后,主机可以访问虚拟机上的服务(如数据库)。

 

第二种:Bridged Adapter模式

网桥模式是我最喜欢的用的一种模式,同时,模拟度也是相当完美。你可以这样理解,它是通过主机网卡,架设了一条桥,直接连入到网络中了。因此,它使得虚拟机能被分配到一个网络中独立的IP,所有网络功能完全和在网络中的真实机器一样。

 

虚拟机与主机关系:可以相互访问,因为虚拟机在真实网络段中有独立IP,主机与虚拟机处于同一网络段中,彼此可以通过各自IP相互访问。

 

虚拟机于网络中其他主机关系:可以相互访问,同样因为虚拟机在真实网络段中有独立IP,虚拟机与所有网络其他主机处于同一网络段中,彼此可以通过各自IP相互访问。

 

虚拟机于虚拟机关系:可以相互访问,原因同上。

 

IP:一般是DHCP分配的,与主机的“本地连接”的IP 是同一网段的。虚拟机就能与主机互相通信。

 

笔记本已插网线时:(若网络中有DHCP服务器)主机与虚拟机会通过DHCP分别得到一个IP,这两个IP在同一网段。 主机与虚拟机可以ping通,虚拟机可以上互联网。

 

笔记本没插网线时:主机与虚拟机不能通信。主机的“本地连接”有红叉,就不能手工指定IP。虚拟机也不能通过DHCP得到IP地址,手工指定IP后,也无法与主机通信,因为主机无IP。

 

这时主机的VirtualBox Host-Only Network 网卡是有ip的,192.168.56.1。虚拟机就算手工指定了IP 192.168.56.*,也ping不能主机。

 

第三种:Internal模式

内网模式,顾名思义就是内部网络模式,虚拟机与外网完全断开,只实现虚拟机于虚拟机之间的内部网络模式。

 

虚拟机与主机关系:不能相互访问,彼此不属于同一个网络,无法相互访问。

虚拟机与网络中其他主机关系:不能相互访问,理由同上。

虚拟机与虚拟机关系:可以相互访问,前提是在设置网络时,两台虚拟机设置同一网络名称。如上配置图中,名称为intnet。

 

IP: VirtualBox的DHCP服务器会为它分配IP ,一般得到的是192.168.56.101,因为是从101起分的,也可手工指定192.168.56.*。

 

笔记本已插网线时:虚拟机可以与主机的VirtualBox Host-Only Network 网卡通信

 

这种方案不受主机本地连接(网卡)是否有红叉的影响。

 

第四种:Host-only Adapter模式

主机模式,这是一种比较复杂的模式,需要有比较扎实的网络基础知识才能玩转。可以说前面几种模式所实现的功能,在这种模式下,通过虚拟机及网卡的设置都可以被实现。

 

我们可以理解为Vbox在主机中模拟出一张专供虚拟机使用的网卡,所有虚拟机都是连接到该网卡上的,我们可以通过设置这张网卡来实现上网及其他很多功能,比如(网卡共享、网卡桥接等)。

 

虚拟机与主机关系:默认不能相互访问,双方不属于同一IP段,host-only网卡默认IP段为192.168.56.X 子网掩码为255.255.255.0,后面的虚拟机被分配到的也都是这个网段。通过网卡共享、网卡桥接等,可以实现虚拟机于主机相互访问。

 

虚拟机与网络主机关系:默认不能相互访问,原因同上,通过设置,可以实现相互访问。

 

虚拟机与虚拟机关系:默认可以相互访问,都是同处于一个网段。

 

虚拟机访问主机:用的是主机的VirtualBox Host-Only Network网卡的IP:192.168.56.1  ,不管主机“本地连接”有无红叉,永远通。

 

主机访问虚拟机:用是的虚拟机的网卡3的IP: 192.168.56.101  ,不管主机“本地连接”有无红叉,永远通。

 

虚拟机访问互联网,用的是自己的网卡2, 这时主机要能通过“本地连接”有线上网,(无线网卡不行)

 

通过对以上几种网络模式的了解,我们就可以灵活运用,模拟组建出我们所想要的任何一种网络环境了。

 

比 如我想模拟出来一个一台主机,监控一个局域网上网情况的网络环境。首先我开启了两台虚拟机vhost1与vhost2,当然如果硬件允许,我同样可以再增 加vhost3、vhost4…所有的vhost我都设置成internat内网模式,网络名称为intnal,网关为192.168.56.100,意 思就是通过192.168.56.100网卡上网。其中有一台vhost1我设置为双网卡,一张为内网模式(192.168.56.100),一张为网桥 模式(192.168.1.101)。两张网卡设置双网卡共享上网。

 

虚拟机之间为局域网,其中有一台虚拟机vhost1通过与外网相连,所有局域网中的虚拟机又通过vhost1来实现上外网。这样vhost1就可以监控整个虚拟机局域网上网情况了。


摘自:http://blog.163.com/paladin_stalin/blog/static/16470658920111121103740814/

http://www.07net01.com/linux/VitualBoxwangluolianjiexingshi_37824_1354863027.html

2013年6月21日星期五

【转】sql server和mysql变量赋值的区别 以及 MySql Declare

sql server和mysql都是我们经常用到的数据库系统,下面就为您介绍sql server和mysql变量赋值的区别,希望对您能有所启迪。

sql server中变量要先申明后赋值:

局部变量用一个@标识,全局变量用两个@(常用的全局变量一般都是已经定义好的);

申明局部变量语法:declare @变量名 数据类型;例如:declare @num int;

赋值:有两种方法式(@num为变量名,value为值)

set @num=value;   或   select @num=value;

如果想获取查询语句中的一个字段值可以用select给变量赋值,如下:

select @num=字段名 from 表名 where ……

mysql变量赋值不用事前申明,在用的时候直接用“@变量名”使用就可以了。

第一种用法:set @num=1; 或set @num:=1; //这里要使用变量来保存数据,直接使用@num变量

第二种用法:select @num:=1; 或 select @num:=字段名 from 表名 where …… (张英:似乎mysql中不能使用 select @p1 := c1, @p2:=c2 from tb 方式赋值)

注意上面两种赋值符号,使用set时可以用“=”或“:=”,但是使用select时必须用“:=赋值”


mysql可以在SP中声明不带@的局部变量,具体见declare。

 

Declare

 

20.2.8. DECLARE语句

DECLARE语句被用来把不同项目局域到一个 子程序:局部变量(请参阅20.2.9节,“存储程序中的变量”),条件和 处理程序(请参阅20.2.10节,“条件和处理程序”) 及光标(请参阅20.2.11节,“光标”)。SIGNAL和RESIGNAL语句当前还不被支持。

DECLARE仅被用在BEGIN ... END复合语句里,并且必须在复合语句的开头,在任何其它语句之前。

光标必须在声明处理程序之前被声明,并且变量和条件必须在声明光标或处理程序之前被声明。

20.2.9. 存储程序中的变量

你可以在子程序中声明并使用变量。

20.2.9.1. DECLARE局部变量

DECLARE var_name[,...] type [DEFAULT value]

这个语句被用来声明局部变量。要给变量提供一个默认值,请包含一个DEFAULT子句。值可以被指定为一个表达式,不需要为一个常数。如果没有DEFAULT子句,初始值为NULL。

局部变量的作用范围在它被声明的BEGIN ... END块内。它可以被用在嵌套的块中,除了那些用相同名字 声明变量的块。

20.2.9.2. 变量SET语句

  SET var_name = expr [, var_name = expr] ...

在存储程序中的SET语句是一般SET语句的扩展版本。被参考变量可能是子程序内声明的变量,或者是全局服务器变量。

在 存储程序中的SET语句作为预先存在的SET语法的一部分来实现。这允许SET a=x, b=y, ...这样的扩展语法。其中不同的变量类型(局域 声明变量及全局和集体变量)可以被混合起来。这也允许把局部变量和一些只对系统变量有意义的选项合并起来。在那种情况下,此选项被识别,但是被忽略了。

20.2.9.3. SELECT ... INTO语句

SELECT col_name[,...] INTO var_name[,...] table_expr

这个SELECT语法把选定的列直接存储到变量。因此,只有单一的行可以被取回。

SELECT id,data INTO x,y FROM test.t1 LIMIT 1;

注意,用户变量名在MySQL 5.1中是对大小写不敏感的。请参阅9.3节,“用户变量”

重要: SQL变量名不能和列名一样。如果SELECT ... INTO这样的SQL语句包含一个对列的参考,并包含一个与列相同名字的 局部变量,MySQL当前把参考解释为一个变量的名字。例如,在下面的语句中,xname 被解释为到xname variable 的参考而不是到xname column的:

  CREATE PROCEDURE sp1 (x VARCHAR(5))
 BEGIN
    DECLARE xname VARCHAR(5) DEFAULT 'bob';
    DECLARE newname VARCHAR(5);
    DECLARE xid INT;
    
    SELECT xname,id INTO newname,xid 
      FROM table1 WHERE xname = xname;
    SELECT newname;
 END;
当这个程序被调用的时候,无论table.xname列的值是什么,变量newname将返回值‘bob’。

摘自:http://www.cnblogs.com/end/archive/2011/03/30/1999646.html

【转】MYSQL使用游标嵌套的两个实例

在实际业务逻辑开发中,难免用到游标嵌套,举例如下:

delimiter //
drop procedure if exists good_nested_cursors1
//
CREATE   PROCEDURE good_nested_cursors1(  )
   READS SQL DATA
BEGIN
  DECLARE l_grade_id INT;
  DECLARE l_class_id   INT;
  DECLARE l_class_cnt     INT DEFAULT 0 ;
  DECLARE l_done          INT DEFAULT  0;
  
  DECLARE grade_csr cursor  FOR    SELECT grade_id FROM org_grade;
  DECLARE class_csr cursor  FOR     SELECT class_id FROM org_class  WHERE grade_id=l_grade_id;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_done=1;
  OPEN grade_csr;
  grade_loop: LOOP   -- Loop through org_grade
    FETCH grade_csr into l_grade_id;
                select concat('年级:', l_grade_id);
    IF l_done=1 THEN
       LEAVE grade_loop;
    END IF;
    OPEN class_csr;
    SET l_class_cnt=0;
    class_loop: LOOP      -- Loop through class in grade.
      FETCH class_csr INTO l_class_id;
      IF l_done=1 THEN
         LEAVE class_loop;
      END IF;
      SET l_class_cnt=l_class_cnt+1;
      select concat('    班级:', l_class_id);
    END LOOP;
    CLOSE class_csr;
    SET l_done=0;
  
  END LOOP grade_loop;
  CLOSE grade_csr;
END;
//
delimiter ;
///////////////////////////////////////////////////////
//另一个例子:
CREATE PROCEDURE curdemo() 
NOT DETERMINISTIC 
CONTAINS SQL 
SQL SECURITY DEFINER 
COMMENT '' 
BEGIN 
declare done1,done2 int default 0; 
declare name1,name2 varchar(20); 
declare id1,id2 int;
   
declare cur1 cursor for select id,name from test1; 
declare continue handler for not found set done1 = 1;
open cur1;
repeat 
fetch cur1 into id1, name1; 
if not done1 then 
insert into test3(name) values(name1); 
begin 
declare cur2 cursor for select id,name from test2; 
declare continue handler for not found set done2 = 1; 
open cur2; 
repeat 
fetch cur2 into id2,name2; 
if not done2 then 
insert into test3(name) values(name2); 
end if;   
until done2 end repeat; 
close cur2; 
set done2=0; 
end; 
end if; 
until done1 end repeat; 
close cur1;
commit; 
END;
///
作者 蔡磊

摘自:http://www.qi9.cn/html/759_5400.html

【转】mysql 存储过程中使用多游标

mysql的存储过程可以很方便使用游标来实现一些功能,存储过程的写法大致如下:

先创建一张表,插入一些测试数据:

DROP TABLE IF EXISTS netingcn_proc_test;    CREATE TABLE `netingcn_proc_test` (    `id` INTEGER(11) NOT NULL AUTO_INCREMENT,    `name` VARCHAR(20),    `password` VARCHAR(20),    PRIMARY KEY (`id`)  )ENGINE=InnoDB;    insert into netingcn_proc_test(name, password) values  ('procedure1', 'pass1'),  ('procedure2', 'pass2'),  ('procedure3', 'pass3'),  ('procedure4', 'pass4');

下面就是一个简单存储过程的例子:

drop procedure IF EXISTS test_proc;  delimiter //  create procedure test_proc()  begin  	-- 声明一个标志done, 用来判断游标是否遍历完成  	DECLARE done INT DEFAULT 0;    	-- 声明一个变量,用来存放从游标中提取的数据  	-- 特别注意这里的名字不能与由游标中使用的列明相同,否则得到的数据都是NULL  	DECLARE tname varchar(50) DEFAULT NULL;  	DECLARE tpass varchar(50) DEFAULT NULL;    	-- 声明游标对应的 SQL 语句  	DECLARE cur CURSOR FOR  		select name, password from netingcn_proc_test;    	-- 在游标循环到最后会将 done 设置为 1  	DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;    	-- 执行查询  	open cur;  	-- 遍历游标每一行  	REPEAT  		-- 把一行的信息存放在对应的变量中  		FETCH cur INTO tname, tpass;  		if not done then  			-- 这里就可以使用 tname, tpass 对应的信息了  			select tname, tpass;  		end if;   	UNTIL done END REPEAT;  	CLOSE cur;  end  //  delimiter ;    -- 执行存储过程  call test_proc();

需要注意的是变量的声明、游标的声明和HANDLER声明的顺序不能搞错,必须是先声明变量,再申明游标,最后声明HANDLER。上述存储过程的 例子中只使用了一个游标,那么如果要使用两个或者更多游标怎么办,其实很简单,可以这么说,一个怎么用两个就是怎么用的。例子如下:

drop procedure IF EXISTS test_proc_1;  delimiter //  create procedure test_proc_1()  begin  	DECLARE done INT DEFAULT 0;  	DECLARE tid int(11) DEFAULT 0;  	DECLARE tname varchar(50) DEFAULT NULL;  	DECLARE tpass varchar(50) DEFAULT NULL;    	DECLARE cur_1 CURSOR FOR  		select name, password from netingcn_proc_test;    	DECLARE cur_2 CURSOR FOR  		select id, name from netingcn_proc_test;    	DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;    	open cur_1;  	REPEAT  		FETCH cur_1 INTO tname, tpass;  		if not done then  			select tname, tpass;  		end if;   	UNTIL done END REPEAT;  	CLOSE cur_1;    	-- 注意这里,一定要重置done的值为 0  	set done = 0;    	open cur_2;  	REPEAT  		FETCH cur_2 INTO tid, tname;  		if not done then  			select tid, tname;  		end if;   	UNTIL done END REPEAT;  	CLOSE cur_2;  end  //  delimiter ;    call test_proc_1();

上述代码和第一个例子中基本一样,就是多了一个游标声明和遍历游标。这里需要注意的是,在遍历第二个游标前使用了set done = 0,因为当第一个游标遍历玩后其值被handler设置为1了,如果不用set把它设置为 0 ,那么第二个游标就不会遍历了。当然好习惯是在每个打开游标的操作前都用该语句,确保游标能真正遍历。当然还可以使用begin语句块嵌套的方式来处理多 个游标,例如:

drop procedure IF EXISTS test_proc_2;  delimiter //  create procedure test_proc_2()  begin  	DECLARE done INT DEFAULT 0;  	DECLARE tname varchar(50) DEFAULT NULL;  	DECLARE tpass varchar(50) DEFAULT NULL;    	DECLARE cur_1 CURSOR FOR  		select name, password from netingcn_proc_test;    	DECLARE cur_2 CURSOR FOR  		select id, name from netingcn_proc_test;    	DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;    	open cur_1;  	REPEAT  		FETCH cur_1 INTO tname, tpass;  		if not done then  			select tname, tpass;  		end if;   	UNTIL done END REPEAT;  	CLOSE cur_1;    	begin  		DECLARE done INT DEFAULT 0;  		DECLARE tid int(11) DEFAULT 0;  		DECLARE tname varchar(50) DEFAULT NULL;    		DECLARE cur_2 CURSOR FOR  			select id, name from netingcn_proc_test;    		DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;    		open cur_2;  		REPEAT  			FETCH cur_2 INTO tid, tname;  			if not done then  				select tid, tname;  			end if;  	 	UNTIL done END REPEAT;  		CLOSE cur_2;  	end;  end  //  delimiter ;    call test_proc_2();

摘自:http://www.netingcn.com/mysql-procedure-muti-cursor.html

2013年6月20日星期四

【转】RHEL5.5下载地址及安装序列号

RHEL5的版本:

主要分为Sever和Desktop两个版本。
具体来说,Server版本分为:
・ Red Hat Enterprise Linux Advanced Platform - 对应以前的・ Red Hat Enterprise Linux AS
・ Red Hat Enterprise Linux - 对应以前的Red Hat Enterprise Linux AS
Desktop版本分为:
・ Red Hat Enterprise Linux Desktop - 对应以前的Red Hat Desktop
・ Red Hat Enterprise Linux Desktop with Workstation option - 对应以前的Red Hat Enterprise Linux WS

本软件为Red Hat Enterprise Linux Desktop,与 Sever最大的不同是其内置了OpenOffice,适合桌面应用。这是RHEL 5第5个更新版。
rhel-client-5.5-i386-dvd 为RHEL 5 Update 5 Client 版操作系统盘。
server版可见 http://www.VeryCD.com/topics/2766897/

 

中文名: 红帽企业Linux 5.5 for x86_64 桌面版
英文名: Red Hat Enterprise Linux Client 5.5 for x86_64
别名: RHEL Client 5.5
资源格式: 光盘镜像
版本: 5.5
制作发行: redhat
http://www.redhat.com/

 

verycd下载地址:

[红帽Linux.5.5.for.x86.服务器版].rhel-server-5.5-i386-dvd.iso

ed2k://|file|%5B%E7%BA%A2%E5%B8%BDLinux.5.5.for.x86.%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%89%88%5D.rhel-server-5.5-i386-dvd.iso|3111600128|c31ef40064e8ad1a1f59078c39a4bbda|h=7dktorhoclc3vxgssp3rovehomd2bfii|/

[红帽企业Linux.5.5.for.x86_64.桌面版].[i.Studio]rhel-client-5.5-x86_64-dvd.iso

ed2k://|file|%5B%E7%BA%A2%E5%B8%BD%E4%BC%81%E4%B8%9ALinux.5.5.for.x86_64.%E6%A1%8C%E9%9D%A2%E7%89%88%5D.%5Bi.Studio%5Drhel-client-5.5-x86_64-dvd.iso|4681160704|b18cf2a3e8ab05f27e90e7eb6af13827|h=flcggvznskxccfg2kre4ivtpfu7worzq|/

RHEL 5 安装序列号
安装序列号被用来配置安装程序来提供正确的软件包。如果您没有输入安装号码,只有核心服务器或 Desktop 将会被安装。其它功能可以在以后被手工安装。这个安装序列号并不是说能让你一直去升级享受官方的服务,只是能让你装上并试用30天而已,30天以后yum 将无法使用官方的源更新。当然系统还是可以用的,只是不能用官方的补丁包。你可以自己去下包来升级或者能找到非官方的源,如CentOS的源。
不管有没有序列号,不影响任何功能组件的安装!有序列号可以享受Redhat的30天的免费更新服务,没有序列号则得不到官方的更新补丁。序列号可以在Redhat网站上免费申请。关于安装号码的更多信息,请参考
http://www.redhat.com/apps/support/in.html )


服务器:
* Red Hat Enterprise Linux (Server including virtualization):
2515dd4e215225dd
+ Red Hat Enterprise Linux Virtualization Platform:
49af89414d147589
客户端:
* Red Hat Enterprise Linux Desktop:
660266e267419c67
+ Red Hat Enterprise Linux Desktop + Workstation Option:
da3122afdb7edd23
+ Red Hat Enterprise Linux Desktop + Workstation + DualOS Option
(Virtualization):
7fcc43557e9bbc42
+ Red Hat Enterprise Linux Desktop + DualOS Option (Virtualization):
fed67649ff918c77

摘自:http://blog.csdn.net/linglong228/article/details/6597287

【转】关于RHEL 5的安装号

 RHEL 5在安装的时候会提示输入一个安装号,这个安装号不是序列号

  安装号的目的是为了保证安装的组件和订阅内容相匹配(这是指购买介质时候选择的功能),红帽企业 Linux 5 需要输入一个安装号。它被用来配置安装程序来提供正确的软件包。(具体意思是输了安装号你就可以不用选择要安装那些组件,因为每个安装号包含了预先设置好 的安装组件)

  如果没有输入安装号码,只有核心服务器将会被安装。其它功能可以在以后被手工安装,功能上没有任何限制,只是多了一道安装手续而已,安装好了的服务器没有任何功能上的不同。



2515-dd4e-2152-25dd

摘自:http://www.linuxdiyf.com/viewarticle.php?id=85840

2013年6月15日星期六

【转】JS类库CDN

摘自:http://www.sourcejoy.com/js-cdn.html


现在web应用都在使用JS类库,这些类库小的几十K,大的几百K,而国内网络访问速度大家都知道不是那么惬意,所以给各位开发者推荐常用JS类库的CDN缓存,这样不管客户在哪里访问你的页面,调用公共类库的速度都会为你的页面节省很多时间。


GOOGLE的js类库CDN发布页:
http://code.google.com/intl/zh-CN/apis/libraries/


微软的js库CDN发布页:
http://www.asp.net/ajaxlibrary/cdn.ashx


百度的

http://developer.baidu.com/wiki/index.php?title=docs/cplat/libs


新浪的

http://lib.sinaapp.com/

2013年6月9日星期日

【转】TortoiseSVN解决冲突

解决冲突Resolving Conflicts
有时候,你从仓库更新文件时会 发生一些冲突。当两个或更多开发人员对同一个文件的某几行做了修改,就会产生冲突。因为Subversion对你的项目一无所知,他会把冲突留给开发人员 来解决。只要冲突产生了,你就应该打开有问题的文件,然后找到以“<<<<<<<”开头的那几行,有冲突的区 域会被下面这样标示:

<<<<<<< filename

    your changes

=======

    code merged from repository

>>>>>>> revision

另外,对每一个有冲突的文件,Subversion都会在你的目录中放三个另外的文件:

filename.ext.mine

这个文件是更新工作副本之前,冲突文件在你的工作副本中原来的样子。其中没有任何冲突标记。

filename.ext.rOLDREV

这个文件是版本号为OLDREV时的文件。也就是你做修改之前最后一次取出的文件。

filename.ext.rNEWREV

这是你更新时Subversion客户端从服务器收到的最新版本的文件。他是仓库的最新版本。

你可以在菜单中选择Edit Conflict来打开一个合并工具或冲突编辑器,或者用其他编辑器来解决这个冲突。你必须决定这些代码到底该是什么样子,做一些必要的修改,然后保存文件。

然后选择菜单中的Resolved命令执行,接着提交修改到仓库。请注意,命令Resolved并没有真正的解决冲突,它只不过是把filename.ext.mine 和 filename.ext.r*删除,并允许你提交修改而已。

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/happy4nothing/archive/2005/05/23/376604.aspx#_Toc101751894

 

先update

TortoiseSVN->dif 进行修改

再Resolved提交


摘自:http://www.cnblogs.com/djian/archive/2010/11/15/1877381.html

【转】25个必须记住的SSH命令

OpenSSH是SSH连接工具的免费版本。telnet,rlogin和ftp用户可能还没意识到他们在互联网上传输的密码是未加密的,但SSH 是加密的,OpenSSH加密所有通信(包括密码),有效消除了窃听,连接劫持和其它攻击。此外,OpenSSH提供了安全隧道功能和多种身份验证方法, 支持SSH协议的所有版本。

SSH是一个非常伟大的工具,如果你要在互联网上远程连接到服务器,那么SSH无疑是最佳的候选。下面是通过网络投票选出的25个最佳SSH命令,你必须牢记于心。

(注:有些内容较长的命令,在本文中会显示为截断的状态。如果你需要阅读完整的命令,可以把整行复制到您的记事本当中阅读。)

1、复制SSH密钥到目标主机,开启无密码SSH登录

ssh-copy-id user@host

如果还没有密钥,请使用ssh-keygen命令生成。

2、从某主机的80端口开启到本地主机2001端口的隧道

ssh -N -L2001:localhost:80 somemachine

现在你可以直接在浏览器中输入http://localhost:2001访问这个网站。

3、将你的麦克风输出到远程计算机的扬声器

dd if=/dev/dsp | ssh -c arcfour -C username@host dd of=/dev/dsp

这样来自你麦克风端口的声音将在SSH目标计算机的扬声器端口输出,但遗憾的是,声音质量很差,你会听到很多嘶嘶声。

4、比较远程和本地文件

ssh user@host cat /path/to/remotefile | diff /path/to/localfile �

在比较本地文件和远程文件是否有差异时这个命令很管用。

5、通过SSH挂载目录/文件系统

sshfs name@server:/path/to/folder /path/to/mount/point

http://fuse.sourceforge.net/sshfs.html下载sshfs,它允许你跨网络安全挂载一个目录。

6、通过中间主机建立SSH连接

ssh -t reachable_host ssh unreachable_host

Unreachable_host表示从本地网络无法直接访问的主机,但可以从reachable_host所在网络访问,这个命令通过到reachable_host的"隐藏"连接,创建起到unreachable_host的连接。

7、将你的SSH公钥复制到远程主机,开启无密码登录 � 简单的方法

ssh-copy-id username@hostname

8、直接连接到只能通过主机B连接的主机A

ssh -t hostA ssh hostB

当然,你要能访问主机A才行。

9、创建到目标主机的持久化连接

ssh -MNf <user>@<host>

在后台创建到目标主机的持久化连接,将这个命令和你~/.ssh/config中的配置结合使用:

Host host  ControlPath ~/.ssh/master-%r@%h:%p  ControlMaster no

所有到目标主机的SSH连接都将使用持久化SSH套接字,如果你使用SSH定期同步文件(使用rsync/sftp/cvs/svn),这个命令将非常有用,因为每次打开一个SSH连接时不会创建新的套接字。

10、通过SSH连接屏幕

ssh -t remote_host screen �r

直接连接到远程屏幕会话(节省了无用的父bash进程)。

11、端口检测(敲门)

knock <host> 3000 4000 5000 && ssh -p <port> user@host && knock <host> 5000 4000 3000

在一个端口上敲一下打开某个服务的端口(如SSH),再敲一下关闭该端口,需要先安装knockd,下面是一个配置文件示例。

[options]  logfile = /var/log/knockd.log  [openSSH]  sequence = 3000,4000,5000  seq_timeout = 5  command = /sbin/iptables -A INPUT -i eth0 -s %IP% -p tcp �dport 22 -j ACCEPT  tcpflags = syn  [closeSSH]  sequence = 5000,4000,3000  seq_timeout = 5  command = /sbin/iptables -D INPUT -i eth0 -s %IP% -p tcp �dport 22 -j ACCEPT  tcpflags = syn

12、删除文本文件中的一行内容,有用的修复

ssh-keygen -R <the_offending_host>

在这种情况下,最好使用专业的工具。

13、通过SSH运行复杂的远程shell命令

ssh host -l user $(<cmd.txt)

更具移植性的版本:

ssh host -l user "`cat cmd.txt`"

14、通过SSH将MySQL数据库复制到新服务器

mysqldump �add-drop-table �extended-insert �force �log-error=error.log -uUSER -pPASS OLD_DB_NAME | ssh -C user@newhost "mysql -uUSER -pPASS NEW_DB_NAME"

通过压缩的SSH隧道Dump一个MySQL数据库,将其作为输入传递给mysql命令,我认为这是迁移数据库到新服务器最快最好的方法。

15、删除文本文件中的一行,修复"SSH主机密钥更改"的警告

sed -i 8d ~/.ssh/known_hosts

16、从一台没有SSH-COPY-ID命令的主机将你的SSH公钥复制到服务器

cat ~/.ssh/id_rsa.pub | ssh user@machine "mkdir ~/.ssh; cat >> ~/.ssh/authorized_keys"

如果你使用Mac OS X或其它没有ssh-copy-id命令的*nix变种,这个命令可以将你的公钥复制到远程主机,因此你照样可以实现无密码SSH登录。

17、实时SSH网络吞吐量测试

yes | pv | ssh $host "cat > /dev/null"

通过SSH连接到主机,显示实时的传输速度,将所有传输数据指向/dev/null,需要先安装pv。

如果是Debian:

apt-get install pv

如果是Fedora:

yum install pv

(可能需要启用额外的软件仓库)。

18、如果建立一个可以重新连接的远程GNU screen

ssh -t user@some.domain.com /usr/bin/screen �xRR

人们总是喜欢在一个文本终端中打开许多shell,如果会话突然中断,或你按下了"Ctrl-a d",远程主机上的shell不会受到丝毫影响,你可以重新连接,其它有用的screen命令有"Ctrl-a c"(打开新的shell)和"Ctrl-a a"(在shell之间来回切换),请访问http://aperiodic.net/screen/quick_reference阅读更多关于 screen命令的快速参考。

19、继续SCP大文件

rsync �partial �progress �rsh=ssh $file_source $user@$host:$destination_file

它可以恢复失败的rsync命令,当你通过VPN传输大文件,如备份的数据库时这个命令非常有用,需要在两边的主机上安装rsync。

rsync �partial �progress �rsh=ssh $file_source $user@$host:$destination_file local -> remote

rsync �partial �progress �rsh=ssh $user@$host:$remote_file $destination_file remote -> local

20、通过SSH W/ WIRESHARK分析流量

ssh root@server.com 'tshark -f "port !22″ -w -' | wireshark -k -i �

使用tshark捕捉远程主机上的网络通信,通过SSH连接发送原始pcap数据,并在wireshark中显示,按下Ctrl+C将停止捕捉,但 也会关闭wireshark窗口,可以传递一个"-c #"参数给tshark,让它只捕捉"#"指定的数据包类型,或通过命名管道重定向数据,而不是直接通过SSH传输给wireshark,我建议你过滤数 据包,以节约带宽,tshark可以使用tcpdump替代:

ssh root@example.com tcpdump -w � 'port !22′ | wireshark -k -i �

21、保持SSH会话永久打开

autossh -M50000 -t server.example.com 'screen -raAd mysession'

打开一个SSH会话后,让其保持永久打开,对于使用笔记本电脑的用户,如果需要在Wi-Fi热点之间切换,可以保证切换后不会丢失连接。

22、更稳定,更快,更强的SSH客户端

ssh -4 -C -c blowfish-cbc

强制使用IPv4,压缩数据流,使用Blowfish加密。

23、使用cstream控制带宽

tar -cj /backup | cstream -t 777k | ssh host 'tar -xj -C /backup'

使用bzip压缩文件夹,然后以777k bit/s速率向远程主机传输。Cstream还有更多的功能,请访问http://www.cons.org/cracauer/cstream.html#usage了解详情,例如:

echo w00t, i'm 733+ | cstream -b1 -t2

24、一步将SSH公钥传输到另一台机器

ssh-keygen; ssh-copy-id user@host; ssh user@host

这个命令组合允许你无密码SSH登录,注意,如果在本地机器的~/.ssh目录下已经有一个SSH密钥对,ssh-keygen命令生成的新密钥可 能会覆盖它们,ssh-copy-id将密钥复制到远程主机,并追加到远程账号的~/.ssh/authorized_keys文件中,使用SSH连接 时,如果你没有使用密钥口令,调用ssh user@host后不久就会显示远程shell。

25、将标准输入(stdin)复制到你的X11缓冲区

ssh user@host cat /path/to/some/file | xclip

你是否使用scp将文件复制到工作用电脑上,以便复制其内容到电子邮件中?xclip可以帮到你,它可以将标准输入复制到X11缓冲区,你需要做的就是点击鼠标中键粘贴缓冲区中的内容。

摘自:http://www.cnblogs.com/weafer/archive/2011/06/10/2077852.html

【转】SVN版本冲突解决详解

版本冲突原因:

假设AB两个用户都在版本号为100的时候,更新了kingtuns.txt这个文件,A用户在修改完成之后提交kingtuns.txt到服务器,这个时候提交成功,这个时候kingtuns.txt文件的版本号已经变成101了。同时B用户在版本号为100kingtuns.txt文件上作修改,修改完成之后提交到服务器时,由于不是在当前最新的101版本上作的修改,所以导致提交失败。

 

版本冲突现象:

冲突发生时,subversion会在当前工作目录中保存所有的目标文件版本[上次更新版本、当前获取的版本(即别人提交的版本)、自己更新的版本、目标文件]

假设文件名是kingtuns.txt

对应的文件名分别是:

kingtuns.txt.r101

kingtuns.txt.r102

kingtuns.txt.mine

kingtuns.txt。同时在目标文件中标记来自不同用户的更改。

 

版本冲突解决:

场景:

1、现在AB两个用户都更新kingtuns.txt文件到本地。

1

 

2、文档中原始文件内容如下:

2

 

 

3A用户修改文件,添加内容“A用户修改内容”完成后提交到服务器

3

4

 

 

 

4B用户修改文件,添加内容“B用户修改内容”完成后提交到服务器

5

 

B用户提交更新至服务器时提示如下:

6

 

B用户将文件提交至服务器时,提示版本过期:首先应该从版本库更新版本,然后去解决冲突,冲突解决后要执行svn resolved(解决),然后在签入到版本库。在冲突解决之后,需要使用svn resolved(解决)来告诉subversion冲突解决,这样才能提交更新。

 

解决冲突有三种选择:

 

A、放弃自己的更新,使用svn revert(回滚),然后提交。在这种方式下不需要使用svn resolved(解决)

 

B、放弃自己的更新,使用别人的更新。使用最新获取的版本覆盖目标文件,执行resolved filename并提交(选择文件右键解决)

 

C、手动解决:冲突发生时,通过和其他用户沟通之后,手动更新目标文件。然后执行resolved filename来解除冲突,最后提交。

 

解决步骤如下:

1、  在当前目录下执行“update”(更新)操作

 

 7

2、  在冲突的文件上(选中文件--右键菜单—TortoiseSVN—Edit conflicts(解决冲突)),出现如下窗口

 

Theirs窗口为服务器上当前最新版本

Mine窗口为本地修改后的版本

Merged窗口为合并后的文件内容显示

     8

3、  如果要使用服务器版本,在Theirs窗口选中差异内容,右键,选择Use this text block(使用这段文本块)。

同理如果要使用本地版本,在协商后,在Mine窗口右键,选择Use this text block(使用这段文本块)。

 

    9

4、  修改完成后,保存kingtuns.txt文件内容。

 

5、  B用户的冲突目录下,选中文件--右键菜单—TortoiseSVN—Resolved(解决)。会列出冲突的文件列表,如果确认已经解决,点OK

10

 

6、  冲突解决

 

      11

7、提交解决冲突后的文件。

 

 12

 

 

如何降低冲突解决的复杂度:

1、当文档编辑完成后,尽快提交,频繁的提交/更新可以降低在冲突发生的概率,以及发生时解决冲突的复杂度。

2、在提交时,写上明确的message,方便以后查找用户更新的原因,毕竟随着时间的推移,对当初更新的原因有可能会遗忘

3、养成良好的使用习惯,使用SVN时每次都是先提交,后更新。每天早上打开后,首先要从版本库获取最新版本。每天下班前必须将已经编辑过的文档都提交到版本库。

 

摘自:http://blog.csdn.net/windone0109/article/details/4857044?reload

2013年6月7日星期五

【转】 MySQL Index详解

①MySQL Index

一、SHOW INDEX会返回以下字段

1、Table 表的名称。

2、 Non_unique 如果索引不能包括重复词,则为0,如果可以则为1。

3、 Key_name 索引的名称

4、 Seq_in_index 索引中的列序列号,从1开始。

5、 Column_name 列名称。

6、 Collation 列以什么方式存储在索引中。在MySQL中,有值‘A’(升序)或NULL(无分类)。

7、Cardinality 索引中唯一值的数目的估计值。通过运行ANALYZE TABLE或myisamchk -a可以更新。基数根据被存储为整数的统计数据来计数,所以即使对于小型表,该值也没有必要是精确的。基数越大,当进行联合时,MySQL使用该索引的机 会就越大。

8、Sub_part 如果列只是被部分地编入索引,则为被编入索引的字符的数目。如果整列被编入索引,则为NULL。

9、 Packed 指示关键字如何被压缩。如果没有被压缩,则为NULL。

10、 Null 如果列含有NULL,则含有YES。如果没有,则该列含有NO。

11、 Index_type 用过的索引方法(BTREE, FULLTEXT, HASH, RTREE)。

12、 Comment 多种评注,您可以使用db_name.tbl_name作为tbl_name FROM db_name语法的另一种形式。这两个语句是等价的:

mysql>SHOW INDEX FROM mytable FROM mydb;

mysql>SHOW INDEX FROM mydb.mytable;

二、使用 CREATE INDEX 创建索引

如果要为已存在的表创建索引,就需要使用 CREATE INDEX 命令或 ALTER TABLE 来创建索引。

CREATEINDEX idxtitle ON tablename (title)

这条命令将创建与 CREATE TABLE 命令相同的索引。

三、使用 ALTER TABLE 创建索引

ALTER TABLE tablename ADD INDEX idxtitle (title)

四、查看和删除索引

我们可以使用以下命令来查看已存在的索引:

SHOW INDEX FROM tablename

DROP INDEX indexname ON tablename

DROP INDEX 将删除 tablename 表上的 indexname 索引,indexname 就是我们创建表时指定的索引名。

########################################

createtable c(id char(20) not null primary key,`index` char(10));

问题1.如果我忘记把id设为主键现在该怎么办?输入什么命令?

ALTER TABLE record 

ADD PRIMARY KEY (id); 

例如:ALTER TABLE `abc` ADD PRIMARY KEY(`a`); 

问题2.如果我想把id设为主键,同时想把name改为not null,且改为varchar(10),能不能用一句命令完成问题2?

ALTER TABLE record

ADD PRIMARY KEY (id),

CHANGEname varchar(10) not null;

########################################

索引 mysql index

        索引是一种数据结构,可以是B-tree, R-tree, 或者 hash 结构。其中R-tree 常用于查询比较接近的数据;B-trees适合用于查找某范围内的数据,可以很快的从当前数据找到下条数据;hash结构则适用于随机访问的场合,查找每 条数据的时间几乎相同。显然,若要查找某个时间段的数据,用B-tree结构要比hash结构快好多。  

       优化查询的有效方法是为经常查询的字段建立索引,如无索引查询数据时,会遍历整张表(多么恐怖啊);若有了索引查找会容易很多。当进行 UPDATE, DELETE, 以及 INSERT 操作时,mysql会自动更新索引信息。

1.创建和删除索引( Creating and dropping indexes )

创建:

[xhtml] view plaincopy
  1. mysql> USE sakila;  
  2. Database changed  
  3. mysql> CREATE INDEX idx_actor_first_name ON actor (first_name);  
  4. 或者  
  5. mysql> ALTER TABLE actor ADD INDEX idx_actor_first_name (first_name);  

PS:当用 create index 创建索引时,必须指定索引的名字,否则mysql会报错;
  用 ALTER TABLE 创建索引时,可以不指定索引名字,若不指定mysql会自动生成索引名字
  
建立索引时,若不想用存储引擎的默认索引类型,可以指定索引的类型:

  1. mysql> ALTER TABLE temp_index  
  2.  ADD INDEX (first_name),  
  3.  ADD INDEX lname (last_name) USING BTREE  

删除:

  1. DROP INDEX indexname ON tblname  
  2. mysql> DROP INDEX idx_actor_fname ON actor;  
  3. mysql> ALTER TABLE actor DROP INDEX idx_actor_fname;  

2.索引类型

BTREE    适合连续读取数据
RTREE    适合根据一条数据找附近的数据
HASH      适合随机读取数据
FULLTEXT    
SPATIAL

 查看某个表中存在的索引类型

  1. mysql> SELECT INDEX_NAME,INDEX_TYPE  
  2. -> FROM INFORMATION_SCHEMA.STATISTICS  
  3. -> WHERE TABLE_NAME=’temp_index’;  
  4. +------------+------------+  
  5. | INDEX_NAME | INDEX_TYPE |  
  6. +------------+------------+  
  7. | first_name | HASH       |  
  8. | lname      | BTREE      |  
  9. +------------+------------+  

3.索引冗余

如果两个或者多个索引包含了相同的索引信息,那么就存在索引冗余。

不同类型的索引有不同的索引冗余判断:
(1) SPATIAL 索引
SPATIAL 只能是一个简单索引,不能说复合索引;存在冗余的情况是同一个字段有两个索引。
(2) FULLTEXT 索引
若一个FULLTEXT索引是另一个索引的子集(不考虑字段顺序),则存在冗余。
例如: 表中包含如下两个索引 
■ (field1)
■ (field1, field2)
(3) HASH 索引
若一个索引在不考虑字段顺序的情况下,索引字段相同,则存在冗余。
例如:表中包含如下两个索引 
■ (field1, field2, field3)
■ (field1, field3, field2)
(4) BTREE 索引
若一个索引是另一个索引的子集(考虑字段顺序),则存在冗余。
例如:表中包含如下两个索引 
■ (field2)
■ (field2, field1)

PS:若两个或多个索引有相同的索引字段和字段顺序,但是有不同的索引类型,这样的索引是不冗余的。因为每种索引类型有自己的索引值。

######################################

深入MySQL数据库的索引 

摘要:本文介绍索引的类型,已经如何创建索引做了介绍,其中涉及三个比较重要的SQL语句――ALTER TABLE、CREATE/DROP INDEX和CREATE TABLE,注意它们的用法。

索引是加速表内容访问的主要手段,特别对涉及多个表的连接的查询更是如此。这是数据库优化中的一个重要内容,我们要了解为什么需要索引,索引如何工作以及怎样利用它们来优化查询。本节中,我们将介绍索引的特点,以及创建和删除索引的语法。 

索引的特点

所有的MySQL列类型能被索引。在相关的列上的使用索引是改进SELECT操作性能的最好方法。

一个表最多可有16个索引。最大索引长度是256个字节,尽管这可以在编译MySQL时被改变。

对于CHAR和 VARCHAR列,你可以索引列的前缀。这更快并且比索引整个列需要较少的磁盘空间。对于BLOB和TEXT列,你必须索引列的前缀,你不能索引列的全部。

MySQL能在多个列上创建索引。一个索引可以由最多15个列组成。(在CHAR和VARCHAR列上,你也可以使用列的前缀作为一个索引的部分)。

虽然随着 MySQL 的进一步开发创建索引的约束将会越来越少,但现在还是存在一些约束的。下面的表根据索引的特性,给出了 ISAM 表和 MyISAM 表之间的差别:

表2-1 通道信息特征字对照表索引的特点 ISAM 表 MyISAM 表

NULL 值

BLOB 和 TEXT 列

每个表中的索引数

每个索引中的列数

最大索引行尺寸

不允许

不能索引

16

16

256 字节 允许

只能索引列的前缀

32

16

500 字节

从此表中可以看到,对于 ISAM 表来说,其索引列必须定义为 NOT NULL,并且不能对 BLOB 和 TEXT 列进行索引。MyISAM 表类型去掉了这些限制,而且减缓了其他的一些限制。两种表类型的索引特性的差异表明,根据所使用的 MySQL 版本的不同,有可能对某些列不能进行索引。例如,如果使用3.23 版以前的版本,则不能对包含 NULL 值的列进行索引。

索引有如下的几种情况:

INDEX索引:通常意义的索引,某些情况下KEY是它的一个同义词。索引的列可以包括重复的值。

UNIQUE索引:唯一索引,保证了列不包含重复的值,对于多列唯一索引,它保证值的组合不重复。

PRIMARY KEY索引:也UNIQUE索引非常类似。事实上,PRIMARYKEY索引仅是一个具有PRIMARY名称的UNIQUE索引。这表示一个表只能包含一个PRIMARY KEY。 

用Alter Table语句创建与删除索引

为了给现有的表增加一个索引,可使用 ALTER TABLE 或CREATE INDEX 语句。ALTER TABLE 最常用,因为可用它来创建普通索引、UNIQUE 索引或 PRIMARY KEY 索引,如:

ALTER TABLE tbl_name ADD INDEX index_name  (column_list)

ALTER TABLE tbl_name ADD UNIQUE index_name  (column_list)

ALTER TABLE tbl_name ADD PRIMARY KEY index_name  (column_list)

其中 tbl_name 是要增加索引的表名,而 column_list 指出对哪些列进行索引。一个(col1,col2,...)形式的列表创造一个多列索引。索引值有给定列的值串联而成。如果索引由不止一列组成,各列名之 间用逗号分隔。索引名 index_name 是可选的,因此可以不写它,MySQL 将根据第一个索引列赋给它一个名称。ALTER TABLE 允许在单个语句中指定多个表的更改,因此可以在同时创建多个索引。

同样,也可以用ALTER TABLE语句删除列的索引:

ALTER TABLE tbl_name DROP INDEX index_name

ALTER TABLE tbl_name DROP PRIMARY KEY

注意上面第一条语句可以用来删除各种类型的索引,而第三条语句只在删除 PRIMARY KEY 索引时使用;在此情形中,不需要索引名,因为一个表只可能具有一个这样的索引。如果没有明确地创建作为 PRIMARY KEY 的索引,但该表具有一个或多个 UNIQUE 索引,则 MySQL 将删除这些 UNIQUE 索引中的第一个。

如果从表中删除了列,则索引可能会受到影响。如果所删除的列为索引的组成部分,则该列也会从索引中删除。如果组成索引的所有列都被删除,则整个索引将被删除。

例如,对于上面所使用的student为例,你可能想为之创建这样的索引,以加速表的检索速度:

mysql> ALTER TABLE student

-> ADD PRIMARY KEY(id),

-> ADD INDEXmark(english,Chinese,history);

这个例子,既包括PRIMARY索引,也包括多列索引。记住,使用 PRIMARY索引的列,必须是一个具有NOT NULL属性的列,如果你愿意查看创建的索引的情况,可以使用SHOW INDEX语句:

mysql> SHOW INDEX FROM student;

其结果为:

+---------+------------+----------+--------------+-------------+-

| Table  | Non_unique | Key_name | Seq_in_index | Column_name |

+---------+------------+----------+--------------+-------------+-

| student |          0 | PRIMARY  |           1 | id          |

| student |          1 | mark     |            1 | english     |

| student |          1 | mark     |            2 | chinese     |

| student |          1 | mark     |            3 | history     |

+---------+------------+----------+--------------+-------------+-

由于列数太多,上表并没有包括所有的输出,读者可以试着自己查看。

再使用ALTER TABLE语句删除索引,删除索引需要知道索引的名字,你可以通过SHOW INDEX语句得到:

mysql> ALTER TABLE student DROP PRIMARYKEY,

   -> DROP INDEX mark;

再产看表中的索引,其语句和输出为:

mysql> SHOW INDEX FROM student;

Empty set (0.01 sec) 

用CREATE\DROP INDEX创建索引

还可以用CREATE INDEX语句来创建索引.CREATE INDEX 是在 MySQL 3.23版中引入的,但如果使用3.23 版以前的版本,可利用 ALTER TABLE 语句创建索引(MySQL 通常在内部将 CREATE INDEX 映射到 ALTER TABLE)。该语句创建索引的语法如下:

CREATE UNIQUE INDEX index_name ON tbl_name(column_list)

CREATE INDEX index_name ON tbl_name(column_list) tbl_name、index_name 和 column_list 具有与 ALTER TABLE 语句中相同的含义。这里索引名不可选。很明显,CREATE INDEX 可对表增加普通索引或 UNIQUE 索引,不能用 CREATE INDEX 语句创建 PRIMARY KEY 索引。

可利用 DROP INDEX语句来删除索引。类似于 CREATE INDEX 语句,DROP INDEX 通常在内部作为一条 ALTER TABLE 语句处理,并且DROP INDEX是在 MySQL 3.22 中引入的。

删除索引语句的语法如下:

DROP INDEX index_name ON tbl_name

还是上一节的例子,由于CREATE INDEX不能创建PRIMARY索引,所以这里我们只创建一个多列索引:

mysql> CREATE INDEX mark ONstudent(english,chinese,history);

同样的检查student表,可知:

mysql> SHOW INDEX FROM student;

+---------+------------+----------+--------------+-------------+

| Table  | Non_unique | Key_name | Seq_in_index | Column_name |

+---------+------------+----------+--------------+-------------+

| student |          1 | mark     |           1 | english     |

| student |          1 | mark     |            2 | chinese     |

| student |          1 | mark     |            3 | history     |

+---------+------------+----------+--------------+-------------+

然后使用下面的语句删除索引:

mysql> DROP INDEX mark ON student;

在创建表时指定索引

要想在发布 CREATE TABLE 语句时为新表创建索引,所使用的语法类似于 ALTER TABLE 语句的语法,但是应该在您定义表列的语句部分指定索引创建子句,如下所示:

  1. CREATE TABLE tbl_name  
  2. (  
  3. …  
  4. INDEX index_name (column_list),  
  5. KEY index_name (column_list),  
  6. UNIQUE index_name (column_list),  
  7. PRIMARY KEY index_name (column_list),  
  8. …  
  9. )  

与ALTER TABLE 一样,索引名对于 INDEX 和 UNIQUE 都是可选的,如果未给出,MySQL 将为其选一个。另外,这里KEY时INDEX的一个别名,具有相同的意义。

有一种特殊情形:可在列定义之后增加 PRIMARY KEY 创建一个单列的PRIMARY KEY 索引,如下所示:

  1. CREATE TABLE tbl_name  
  2. (  
  3.   iINT NOT NULL PRIMARY KEY  
  4. )  

该语句等价于以下的语句:

  1. CREATE TABLE tbl_name  
  2. (  
  3.   iINT NOT NULL,  
  4.  PRIMARY KEY (i)  
  5. )  

前面所有表创建样例都对索引列指定了 NOT NULL。如果是 ISAM 表,这是必须的,因为不能对可能包含 NULL 值的列进行索引。如果是 MyISAM 表,索引列可以为 NULL,只要该索引不是 PRIMARY KEY 索引即可。

在CREATE TBALE语句中可以某个串列的前缀进行索引(列值的最左边 n 个字符)。

如果对某个串列的前缀进行索引,应用 column_list 说明符表示该列的语法为 col_name(n) 而不用col_name。例如,下面第一条语句创建了一个具有两个 CHAR 列的表和一个由这两列组成的索引。第二条语句类似,但只对每个列的前缀进行索引:

  1. CREATE TABLE tbl_name  
  2. (  
  3. name CHAR(30),  
  4. address CHAR(60),  
  5. INDEX (name,address)  
  6. )  
  1. CREATE TABLE tbl_name  
  2. (  
  3. name CHAR(30),  
  4. address CHAR(60),  
  5. INDEX (name(10),address(20))  
  6. )  

你可以检查所创建表的索引:

mysql> SHOW INDEX FROM tbl_name;

+----------+------------+----------+--------------+-------------+-

| Table   | Non_unique | Key_name | Seq_in_index | Column_name |

+----------+------------+----------+--------------+-------------+-

| tbl_name |          1 | name     |            1 | name        |

| tbl_name |          1 | name     |            2 | address     |

+----------+------------+----------+--------------+-------------+-

在某些情况下,可能会发现必须对列的前缀进行索引。例如,索引行的长度有一个最大上限,因此,如果索引列的长度超过了这个上限,那么就可能需要利用前缀进行索引。在 MyISAM 表索引中,对 BLOB 或 TEXT 列也需要前缀索引。

对一个列的前缀进行索引限制了以后对该列的更改;不能在不删除该索引并使用较短前缀的情况下,将该列缩短为一个长度小于索引所用前缀的长度的列。 

总结

本节对索引的类型,已经如何创建索引做了介绍,其中涉及三个比较重要的SQL语句――ALTER TABLE、CREATE/DROP INDEX和CREATE TABLE,注意它们的用法。

索引最重要的功能是,通过使用索引加速表的检索,有关这方面的知识,将在第十章数据库优化中介绍。 

思考题

1、建立一个如下所述的表:

data:FLOAT列,使用随机函数填充数据

birth:DATETIME列,填充当前时间。

然后,请录入几条数据。最后计算data列的平均值、总和、极值,并且按照data列降序排序检索值。

2、分别使用标准SQL模式和扩展正规表达式模式匹配,匹配上面创建的表,假设你创建表的当前日期为2001-01-01,用模式匹配检索出birth列包含该日期的值。(实际上,上面的表中记录都是同一日期录入的,因此实际将返回全部记录。)

3、为前几章使用的数据表创建索引:

student:为id段创建一个PRIMARY索引,为english、chinese和history创建一个多列索引。

pet:为name和owner段创建一个多类索引。

4、删除为pet表创建的索引。

##################################################

MySQL Index的使用

以下是理论知识备忘:

一、什么是索引?
   索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存。如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个 表的所有记录,直至找到符合要求的记录。表里面的记录数量越多,这个操作的代价就越高。如果作为搜索条件的列上已经创建了索引,MySQL无需扫描任何记 录即可迅速得到目标记录所在的位置。如果表有1000个记录,通过索引查找记录至少要比顺序扫描记录快100倍。
  
  假设我们创建了一个名为people的表:
  
  CREATE TABLE people ( peopleid SMALLINT NOT NULL, name CHAR(50) NOT NULL );
  
  然后,我们完全随机把1000个不同name值插入到people表。下图显示了people表所在数据文件的一小部分:
  
  可以看到,在数据文件中name列没有任何明确的次序。如果我们创建了name列的索引,MySQL将在索引中排序name列:
  
   对于索引中的每一项,MySQL在内部为它保存一个数据文件中实际记录所在位置的“指针”。因此,如果我们要查找name等于“Mike”记录的 peopleid(SQL命令为“SELECT peopleid FROM people WHERE name='Mike';”),MySQL能够在name的索引中查找“Mike”值,然后直接转到数据文件中相应的行,准确地返回该行的 peopleid(999)。在这个过程中,MySQL只需处理一个行就可以返回结果。如果没有“name”列的索引,MySQL要扫描数据文件中的所有 记录,即1000个记录!显然,需要MySQL处理的记录数量越少,则它完成任务的速度就越快。
  
  二、索引的类型
  MySQL提供多种索引类型供选择:
  
  普通索引
  这是最基本的索引类型,而且它没有唯一性之类的限制。普通索引可以通过以下几种方式创建:
  创建索引,例如CREATE INDEX <索引的名字> ON tablename (列的列表);
  修改表,例如ALTER TABLE tablename ADD INDEX [索引的名字] (列的列表);
  创建表的时候指定索引,例如CREATE TABLE tablename ( [...], INDEX [索引的名字] (列的列表) );
  
  唯一性索引
  这种索引和前面的“普通索引”基本相同,但有一个区别:索引列的所有值都只能出现一次,即必须唯一。唯一性索引可以用以下几种方式创建:
  创建索引,例如CREATE UNIQUE INDEX <索引的名字> ON tablename (列的列表);
  修改表,例如ALTER TABLE tablename ADD UNIQUE [索引的名字] (列的列表);
  创建表的时候指定索引,例如CREATE TABLE tablename ( [...], UNIQUE [索引的名字] (列的列表) );
  
  主键
   主键是一种唯一性索引,但它必须指定为“PRIMARY KEY”。如果你曾经用过AUTO_INCREMENT类型的列,你可能已经熟悉主键之类的概念了。主键一般在创建表的时候指定,例如“CREATE TABLE tablename ( [...], PRIMARY KEY (列的列表) ); ”。但是,我们也可以通过修改表的方式加入主键,例如“ALTER TABLE tablename ADD PRIMARY KEY (列的列表); ”。每个表只能有一个主键。
  
  全文索引
   MySQL从3.23.23版开始支持全文索引和全文检索。在MySQL中,全文索引的索引类型为FULLTEXT。全文索引可以在VARCHAR或者 TEXT类型的列上创建。它可以通过CREATE TABLE命令创建,也可以通过ALTER TABLE或CREATE INDEX命令创建。对于大规模的数据集,通过ALTER TABLE(或者CREATE INDEX)命令创建全文索引要比把记录插入带有全文索引的空表更快。本文下面的讨论不再涉及全文索引,要了解更多信息,请参见MySQL documentation。
  
  三、单列索引与多列索引
  索引可以是单列索引,也可以是多列索引。下面我们通过具体的例子来说明这两种索引的区别。假设有这样一个people表:
  
   CREATE TABLE people ( peopleid SMALLINT NOT NULL AUTO_INCREMENT, firstname CHAR(50) NOT NULL, lastname CHAR(50) NOT NULL, age SMALLINT NOT NULL, townid SMALLINT NOT NULL, PRIMARY KEY (peopleid) );
  
  下面是我们插入到这个people表的数据:
  
  这个数据片段中有四个名字为“Mikes”的人(其中两个姓Sullivans,两个姓McConnells),有两个年龄为17岁的人,还有一个名字与众不同的Joe Smith。
  
   这个表的主要用途是根据指定的用户姓、名以及年龄返回相应的peopleid。例如,我们可能需要查找姓名为Mike Sullivan、年龄17岁用户的peopleid(SQL命令为SELECT peopleid FROM people WHERE firstname='Mike' AND lastname='Sullivan' AND age=17;)。由于我们不想让MySQL每次执行查询就去扫描整个表,这里需要考虑运用索引。
  
   首先,我们可以考虑在单个列上创建索引,比如firstname、lastname或者age列。如果我们创建firstname列的索引(ALTER TABLE people ADD INDEX firstname (firstname);),MySQL将通过这个索引迅速把搜索范围限制到那些firstname='Mike'的记录,然后再在这个“中间结果集”上 进行其他条件的搜索:它首先排除那些lastname不等于“Sullivan”的记录,然后排除那些age不等于17的记录。当记录满足所有搜索条件之 后,MySQL就返回最终的搜索结果。
  
   由于建立了firstname列的索引,与执行表的完全扫描相比,MySQL的效率提高了很多,但我们要求MySQL扫描的记录数量仍旧远远超过了实际 所需要的。虽然我们可以删除firstname列上的索引,再创建lastname或者 age列的索引,但总地看来,不论在哪个列上创建索引搜索效率仍旧相似。
  
  为了提高搜索效率,我们需要考虑运用多列索引。如果为firstname、lastname和age这三个列创建一个多列索引,MySQL只需一次检索就能够找出正确的结果!下面是创建这个多列索引的SQL命令:
  
  ALTER TABLE people ADD INDEX fname_lname_age (firstname,lastname,age);
  
  由于索引文件以B-树格式保存,MySQL能够立即转到合适的firstname,然后再转到合适的lastname,最后转到合适的age。在没有扫描数据文件任何一个记录的情况下,MySQL就正确地找出了搜索的目标记录!
  
   那么,如果在firstname、lastname、age这三个列上分别创建单列索引,效果是否和创建一个firstname、lastname、 age的多列索引一样呢?答案是否定的,两者完全不同。当我们执行查询的时候,MySQL只能使用一个索引。如果你有三个单列的索引,MySQL会试图选 择一个限制最严格的索引。但是,即使是限制最严格的单列索引,它的限制能力也肯定远远低于firstname、lastname、age这三个列上的多列 索引。
  
  四、最左前缀
   多列索引还有另外一个优点,它通过称为最左前缀(Leftmost Prefixing)的概念体现出来。继续考虑前面的例子,现在我们有一个firstname、lastname、age列上的多列索引,我们称这个索引 为fname_lname_age。当搜索条件是以下各种列的组合时,MySQL将使用fname_lname_age索引:
  
  firstname,lastname,age
  firstname,lastname
  firstname
  从另一方面理解,它相当于我们创建了(firstname,lastname,age)、(firstname,lastname)以及(firstname)这些列组合上的索引。下面这些查询都能够使用这个fname_lname_age索引:
  
   SELECT peopleid FROM people WHERE firstname='Mike' AND lastname='Sullivan' AND age='17'; SELECT peopleid FROM people WHERE firstname='Mike' AND lastname='Sullivan'; SELECT peopleid FROM people WHERE firstname='Mike'; The following queries cannot use the index at all: SELECT peopleid FROM people WHERE lastname='Sullivan'; SELECT peopleid FROM people WHERE age='17'; SELECT peopleid FROM people WHERE lastname='Sullivan' AND age='17';
  
  五、选择索引列
  在性能优化过程中,选择在哪些列上创建索引是最重要的步骤之一。可以考虑使用索引的主要有两种类型的列:在WHERE子句中出现的列,在join子句中出现的列。请看下面这个查询:
  
  SELECT age ## 不使用索引
  FROM people WHERE firstname='Mike' ## 考虑使用索引
  AND lastname='Sullivan' ## 考虑使用索引
  
  这个查询与前面的查询略有不同,但仍属于简单查询。由于age是在SELECT部分被引用,MySQL不会用它来限制列选择操作。因此,对于这个查询来说,创建age列的索引没有什么必要。下面是一个更复杂的例子:
  
  SELECT people.age, ##不使用索引
  town.name ##不使用索引
  FROM people LEFT JOIN town ON
  people.townid=town.townid ##考虑使用索引
  WHERE firstname='Mike' ##考虑使用索引
  AND lastname='Sullivan' ##考虑使用索引
  
  与前面的例子一样,由于firstname和lastname出现在WHERE子句中,因此这两个列仍旧有创建索引的必要。除此之外,由于town表的townid列出现在join子句中,因此我们需要考虑创建该列的索引。
  
   那么,我们是否可以简单地认为应该索引WHERE子句和join子句中出现的每一个列呢?差不多如此,但并不完全。我们还必须考虑到对列进行比较的操作 符类型。MySQL只有对以下操作符才使用索引:<,<=,=,>,>=,BETWEEN,IN,以及某些时候的LIKE。可以 在LIKE操作中使用索引的情形是指另一个操作数不是以通配符(%或者_)开头的情形。例如,“SELECT peopleid FROM peopleWHERE firstname LIKE 'Mich%';”这个查询将使用索引,但“SELECT peopleid FROM people WHERE firstname LIKE '%ike';”这个查询不会使用索引。
  
  六、分析索引效率

  现在我们已经知道了一些如何选择索引列的知识,但还无法判断哪一个最有效。MySQL提供了一个内建的SQL命令帮助

一、 MySQL建表,字段需设置为非空,需设置字段默认值。

二、 MySQL建表,字段需NULL时,需设置字段默认值,默认值不为NULL。

三、 MySQL建表,如果字段等价于外键,应在该字段加索引。

四、 MySQL建表,不同表之间的相同属性值的字段,列类型,类型长度,是否非空,是否默认值,需保持一致,否则无法正确使用索引进行关联对比。

五、 MySQL使用时,一条SQL语句只能使用一个表的一个索引。所有的字段类型都可以索引,多列索引的属性最多15个。

六、 如果可以在多个索引中进行选择,MySQL通常使用找到最少行的索引,索引唯一值最高的索引。

七、 建立索引index(part1,part2,part3),相当于建立了 index(part1),index(part1,part2)和index(part1,part2,part3)三个索引。

八、 MySQL针对like语法必须如下格式才使用索引:

SELECT * FROM t1 WHERE key_col LIKE 'ab%' ;

九、 SELECT COUNT(*) 语法在没有where条件的语句中执行效率没有SELECT COUNT(col_name)快,但是在有where条件的语句中执行效率要快。

十、 在where条件中多个and的条件中,必须都是一个多列索引的key_part属性而且必须包含key_part1。各自单一索引的话,只使用遍历最少行的那个索引。

十一、 在where条件中多个or的条件中,每一个条件,都必须是一个有效索引。

十二、 ORDER BY 后面的条件必须是同一索引的属性,排序顺序必须一致(比如都是升序或都是降序)。

十三、 所有GROUP BY列引用同一索引的属性,并且索引必须是按顺序保存其关键字的。

十四、 JOIN 索引,所有匹配ON和where的字段应建立合适的索引。

十五、 对智能的扫描全表使用FORCE INDEX告知MySQL,使用索引效率更高。

十六、 定期ANALYZE TABLE tbl_name为扫描的表更新关键字分布 。

十七、 定期使用慢日志检查语句,执行explain,分析可能改进的索引。

十八、 条件允许的话,设置较大的key_buffer_size和query_cache_size的值(全局参数),和sort_buffer_size的值(session变量,建议不要超过4M)。


摘自:http://blog.csdn.net/tianmo2010/article/details/7930482