什么是MySql数据库
MySql数据库是开放源代码的关系型数据库。目前,它可以提供的功能有:支持sql语言、子查询、存储过程、触发器、视图、索引、事务、锁、外键约束和影像复制等。同Oracle 和SQL Server等大型数据库系统一样,MySql也是客户/服务器系统并且是单进程多线程架构的数据库。并且MySQL是一个真正的多用户、多线程SQL数据库服务器。MySQL的客户机/服务器结构由一个服务器守护程序mysql和很多不同的客户程序和库组成。由于其源码的开放性及稳定性,且与网站流行编徎语言PHP的完美结合,现在很多站点都利用其当作后端数据库,使其获得了广泛应用。MySql区别于其它数据库系统的一个重要特点是支持插入式存储引擎。
那么什么是存储引擎呢?
存储引擎说白了就是如何存储数据、如何为存储的数据建立索引和如何更新、查询数据等技术的实现方法。因为在关系数据库中数据的存储是以表的形式存储的,所以存储引擎也可以称为表类型(即存储和操作此表的类型)。在Oracle 和SQL Server等数据库中只有一种存储引擎,所有数据存储管理机制都是一样的。而MySql数据库提供了多种存储引擎。用户可以根据不同的需求为数据表选择不同的存储引擎,用户也可以根据自己的需要编写自己的存储引擎。那么我的问题是:一个mysql数据库里可以支持多种存储引擎吗?可以为某张表选择一种存储引擎吗? <= 可以。创建数据库的时候有默认存储索引,在创建表的时候可以指定。
插件式存储引擎是MySQL最重要特性之一,也是最不同于其它DBMS的地方。MySQL支持很多存储引擎,以适用于不同的应用需求,常用的包括MyISAM、InnoDB、BDB、MEMORY、MERGE、NDB Cluster等。其中,BDB和NDB Cluster提供事务支持。
MySQL默认的存储引擎为MyISAM,当然,创建表的时候可以指定其它的存储引擎,你可以在同一个数据库中对不同的表使用不同的存储引擎(这是非常强大而独特的特性)。可以通过SHOW TABLE STATUS命令查询表所使用的存储引擎。
MySQL的默认存储引擎,性能与功能的折中,包括全文索引(full-text index)、数据压缩,支持空间(GIS)数据,但是,不支持事务和行级锁。一般来说,MyISAM更适用于大量查询操作。如果你有大量的插入、删除操作,你应该选择InnoDB。
InnoDB是一个高性能的事务存储引擎,此外,BDB也支持事务处理。
MySQL中,支持外键的存储引擎只有InnoDB,在创建外键时,要求被参照表必须有对应的索引,参照表在创建外键时也会自动创建对应的索引。
MySql中有哪些存储引擎?
1. MyISAM:这种引擎是MySql最早提供的, 这种引擎又可以分为静态MyISAM、动态MyISAM 和压缩MyISAM三种,而划分的依据是列的长度是否可以扩展:
静态MyISAM:如果数据表中的各数据列的长度都是预先固定好的,服务器将自动选择这种表类型。因为数据表中每一条记录所占用的空间都是一样的,所以这种表存取和更新的效率非常高。当数据受损时,恢复工作也比较容易做。
动态MyISAM:如果数据表中出现varchar、xxxtext或xxxBLOB字段时,服务器将自动选择这种表类型。相对于静态MyISAM,这种表存储空间比较小,但由于每条记录的长度不一,所以多次修改数据后,数据表中的数据就可能离散的存储在内存中,进而导致执行效率下降。同时,内存中也可能会出现很多碎片。因此,这种类型的表要经常用optimize table命令或优化工具来进行碎片整理。
压缩MyISAM:以上说到的两种类型的表都可以用myisamchk工具压缩。这种类型的表进一步减小了占用的存储,但是这种表压缩之后不能再被修改。另外,因为是压缩数据,所以这种表在读取的时候要先时行解压缩。
但是,不管是何种MyISAM表,目前它都不支持事务,行级锁和外键约束的功能。
2 MyISAM Merge引擎:这种类型是MyISAM类型的一种变种。合并表是将几个相同的MyISAM表合并为一个虚表。常应用于日志和数据仓库。
3 InnoDB:InnoDB表类型可以看作是对MyISAM的进一步更新产品,它提供了事务、行级锁机制和外键约束的功能。
4 memory(heap):这种类型的数据表只存在于内存中。它使用散列索引,所以数据的存取速度非常快。因为是存在于内存中,所以这种类型常应用于临时表中。
5 archive:这种类型只支持select 和 insert语句,而且不支持索引。常应用于日志记录和聚合分析方面。
当然MySql支持的表类型不止上面几种。 下面介绍如何查看和设置数据表类型。
MySql中关于存储引擎的操作:
1. 查看数据库可以支持的存储引擎:show engines,默认数据表类型是MyISAM。当然,我们可以通过修改数据库配置文件中的选项,设定默认表类型。
2.通过显示表的创建语句可以查看该表的Engine, Show create table tablename;
3 设置或修改表的存储引擎,在创建表的语句上加上engine=engineName即可,如:
create table user(
id intnot null auto_increment,
usernamechar(20) not null,
sexchar(2),
primarykey(id)
) engine=merge
而修改存储引擎,使用alter命令,很容易想到,因为Engine是在创建表的时候定好的,顾使用alter来修改,可以用命令Alter table tableName engine =engineName
假如,若需要将表user的存储问引擎修改为archive类型,则可使用命令alter table user engine=archive。
比如在安装Mysql Server5.5的时候,在Mysql Server Instance Configuration, 选择数据库用途的时候,有
Multifunctional Database: The General purpose databases. This will optimize for the use of the fast transactional InnoDB storage engine andhigh speed MyISAM storage engine.
Transactional Database only: Optimized for the application servers and the transactional web applications. This will make the InnoDB the main storage engine. Note the MyISAM storage engine can still be used.
Non-Transactional Database only: Suit for simple web applications, monitoring or logging applications as well as the analysis programs. Only the non-transactional MyISAM storage engine will be activated.
聚集索引
聚集索引确定表中数据的物理顺序。聚集索引类似于电话簿,后者按姓氏排列数据。由于聚集索引规定数据在表中的物理存储顺序,因此一个表只能包含一个聚集索引。但该索引可以包含多个列(组合索引),就像电话簿按姓氏和名字进行组织一样。
聚集索引对于那些经常要搜索范围值的列特别有效。使用聚集索引找到包含第一个值的行后,便可以确保包含后续索引值的行在物理相邻。例如,如果应用程序执行 的一个查询经常检索某一日期范围内的记录,则使用聚集索引可以迅速找到包含开始日期的行,然后检索表中所有相邻的行,直到到达结束日期。这样有助于提高此类查询的性能。同样,如果对从表中检索的数据进行排序时经常要用到某一列,则可以将该表在该列上聚集(物理排序),避免每次查询该列时都进行排序,从而节省成本。 当索引值唯一时,使用聚集索引查找特定的行也很有效率。例如,使用唯一雇员 ID 列 emp_id 查找特定雇员的最快速的方法,是在 emp_id 列上创建聚集索引或 PRIMARY KEY 约束
MySQL主要提供2种方式的索引:B-Tree(包括B+Tree)索引,Hash索引。
B树索引具有范围查找和前缀查找的能力,对于N节点的B树,检索一条记录的复杂度为O(LogN)。
哈希索引只能做等于查找,但是无论多大的Hash表,查找复杂度都是O(1)。
显然,如果值的差异性大,并且以等于查找为主,Hash索引是更高效的选择,它有O(1)的查找复杂度。如果值的差异性相对较差,并且以范围查找为主,B树是更好的选择,它支持范围查找。
MySQL中,只有Memory存储引擎显示支持hash索引,是Memory表的默认索引类型,尽管Memory表也可以使用B-Tree索引。Memory存储引擎支持非唯一hash索引,这在数据库领域是罕见的,如果多个值有相同的hash code,索引把它们的行指针用链表保存到同一个hash表项中。
假设创建如下一个表:
CREATE TABLE testhash (
fname VARCHAR(50) NOT NULL,
lname VARCHAR(50) NOT NULL,
KEY USING HASH(fname)
) ENGINE=MEMORY;
Hash索引有以下一些限制:
(1)由于索引仅包含hash code和记录指针,所以,MySQL不能通过使用索引避免读取记录。但是访问内存中的记录是非常迅速的,不会对性造成太大的影响。
(2)不能使用hash索引排序。
(3)Hash索引不支持键的部分匹配,因为是通过整个索引值来计算hash值的。
(4)Hash索引只支持等值比较,例如使用=,IN( )和<=>。对于WHERE price>100并不能加速查询。
MyISAM和InnoDB的索引:
MyISAM引擎使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址,这种索引方式也叫做“非聚集”的。主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求key是唯一的,而辅助索引的key可以重复。
虽然InnoDB也使用B+Tree作为索引结构,但具体实现方式却与MyISAM截然不同。
第一个重大区别是InnoDB的数据文件本身就是索引文件。MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。在InnoDB中,表数据文件本身就是按B+Tree的一个索引结构,这棵树的叶节点data域保存了完整的数据记录。这个索引的key是数据表的主键,因此InnoDB表数据文件本身就是主索引。这种索引叫做聚集索引。
因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有),如果没有显式指定,则MySQL系统会自动选择第一个可以唯一标识(the first UNIQUE index that has only NOT NULL columns as the primary key)数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整形。
第二个与MyISAM索引的不同是InnoDB的辅助索引data域存储相应记录主键的值而不是地址。换句话说,InnoDB的所有辅助索引都引用主键作为data域。
聚集索引这种实现方式使得按主键的搜索十分高效,但是辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录。
了解不同存储引擎的索引实现方式对于正确使用和优化索引都非常有帮助,例如知道了InnoDB的索引实现后,就很容易明白为什么不建议使用过长的字段作为主键,
因为所有辅助索引都引用主索引,过长的主索引会令辅助索引变得过大。再例如,用非单调的字段作为主键在InnoDB中不是个好主意,
因为InnoDB数据文件本身是一颗B+Tree,非单调的主键会造成在插入新记录时数据文件为了维持B+Tree的特性而频繁的分裂调整,十分低效,而使用自增字段作为主键则是一个很好的选择。
关于索引的使用及优化:
(1)使用组合索引,在sql中使用索引,必须遵循该索引的最左侧原则,否则就用不到该索引。如,给要给表增加索引:
索引存储的值按索引列中的顺序排列。可以利用B-Tree索引进行全关键字、关键字范围和关键字前缀查询,当然,如果想使用索引,你必须保证按索引的最左边前缀(leftmost prefix of the index)来进行查询。
(1)匹配全值(Match the full value):对索引中的所有列都指定具体的值。例如,上图中索引可以帮助你查找出生于1960-01-01的Cuba Allen。
(2)匹配最左前缀(Match a leftmost prefix):你可以利用索引查找last name为Allen的人,仅仅使用索引中的第1列。
(3)匹配列前缀(Match a column prefix):例如,你可以利用索引查找last name以J开始的人,这仅仅使用索引中的第1列。
(4)匹配值的范围查询(Match a range of values):可以利用索引查找last name在Allen和Barrymore之间的人,仅仅使用索引中第1列。
(5)匹配部分精确而其它部分进行范围匹配(Match one part exactly and match a range on another part):可以利用索引查找last name为Allen,而first name以字母K开始的人。
(6)仅对索引进行查询(Index-only queries):如果查询的列都位于索引中,则不需要读取元组的值。
由于B-树中的节点都是顺序存储的,所以可以利用索引进行查找(找某些值),也可以对查询结果进行ORDER BY。当然,使用B-tree索引有以下一些限制:
(1) 查询必须从索引的最左边的列开始。关于这点已经提了很多遍了。例如你不能利用索引查找在某一天出生的人。
(2) 不能跳过某一索引列。例如,你不能利用索引查找last name为Smith且出生于某一天的人。
(3) 存储引擎不能使用索引中范围条件右边的列。例如,如果你的查询语句为WHERE last_name="Smith" AND first_name LIKE 'J%' AND dob='1976-12-23',则该查询只会使用索引中的前两列,因为LIKE是范围查询。
利用索引进行排序
MySQL中,有两种方式生成有序结果集:一是使用filesort,二是按索引顺序扫描。利用索引进行排序操作是非常快的,而且可以利用同一索引同时进行查找和排序操作。当索引的顺序与ORDER BY中的列顺序相同且所有的列是同一方向(全部升序或者全部降序)时,可以使用索引来排序。如果查询是连接多个表,仅当ORDER BY中的所有列都是第一个表的列时才会使用索引。其它情况都会使用filesort。
当MySQL不能使用索引进行排序时,就会利用自己的排序算法(快速排序算法)在内存(sort buffer)中对数据进行排序,如果内存装载不下,它会将磁盘上的数据进行分块,再对各个数据块进行排序,然后将各个块合并成有序的结果集(实际上就是外排序)。对于filesort,MySQL有两种排序算法。
(1) 两遍扫描算法(Two passes)
实现方式是先将须要排序的字段和可以直接定位到相关行数据的指针信息取出,然后在设定的内存(通过参数sort_buffer_size设定)中进行排序,完成排序之后再次通过行指针信息取出所需的Columns。
注:该算法是4.1之前采用的算法,它需要两次访问数据,尤其是第二次读取操作会导致大量的随机I/O操作。另一方面,内存开销较小。
(3) 一次扫描算法(single pass)
该算法一次性将所需的Columns全部取出,在内存中排序后直接将结果输出。
注:从 MySQL 4.1 版本开始使用该算法。它减少了I/O的次数,效率较高,但是内存开销也较大。如果我们将并不需要的Columns也取出来,就会极大地浪费排序过程所需要的内存。在 MySQL 4.1 之后的版本中,可以通过设置 max_length_for_sort_data 参数来控制 MySQL 选择第一种排序算法还是第二种。当取出的所有大字段总大小大于 max_length_for_sort_data 的设置时,MySQL 就会选择使用第一种排序算法,反之,则会选择第二种。为了尽可能地提高排序性能,我们自然更希望使用第二种排序算法,所以在 Query 中仅仅取出需要的 Columns 是非常有必要的。
当对连接操作进行排序时,如果ORDER BY仅仅引用第一个表的列,MySQL对该表进行filesort操作,然后进行连接处理,此时,EXPLAIN输出“Using filesort”;否则,MySQL必须将查询的结果集生成一个临时表,在连接完成之后进行filesort操作,此时,EXPLAIN输出“Using temporary;Using filesort”。
MySQL中,InnoDB和BDB都支持事务处理。这里主要讨论InnoDB的事务处理(关于BDB的事务处理,也十分复杂,以前曾较为详细看过其源码,以后有机会再讨论)。
1.3.1、事务的ACID特性
事务是由一组SQL语句组成的逻辑处理单元,事务具有以下4个属性,通常简称为事务的ACID属性(Jim Gray在《事务处理:概念与技术》中对事务进行了详尽的讨论)。
(1)原子性(Atomicity):事务是一个原子操作单元,其对数据的修改,要么全都执行,要么全都不执行。
(2)一致性(Consistent):在事务开始和完成时,数据都必须保持一致状态。这意味着所有相关的数据规则都必须应用于事务的修改,以保持数据的完整性;事务结束时,所有的内部数据结构(如B树索引或双向链表)也都必须是正确的。
(3)隔离性(Isolation):数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的“独立”环境执行。这意味着事务处理过程中的中间状态对外部是不可见的,反之亦然。
(4)持久性(Durable):事务完成之后,它对于数据的修改是永久性的,即使出现系统故障也能够保持。
1.3.2、事务处理带来的相关问题
由于事务的并发执行,带来以下一些著名的问题:
(1)更新丢失(Lost Update):当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,由于每个事务都不知道其他事务的存在,就会发生丢失更新问题--最后的更新覆盖了由其他事务所做的更新。
(2)脏读(Dirty Reads):一个事务正在对一条记录做修改,在这个事务完成并提交前,这条记录的数据就处于不一致状态;这时,另一个事务也来读取同一条记录,如果不加控制,第二个事务读取了这些“脏”数据,并据此做进一步的处理,就会产生未提交的数据依赖关系。这种现象被形象地叫做"脏读"。
(3)不可重复读(Non-Repeatable Reads):一个事务在读取某些数据后的某个时间,再次读取以前读过的数据,却发现其读出的数据已经发生了改变、或某些记录已经被删除了!这种现象就叫做“不可重复读”。
(4)幻读(Phantom Reads):一个事务按相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足其查询条件的新数据,这种现象就称为“幻读”。
1.3.3、事务的隔离性
SQL2标准定义了四个隔离级别。定义语句如下:
SET TRANSACTION ISOLATION LEVEL
[READ UNCOMMITTED |
READ COMMITTED |
REPEATABLE READ |
SERIALIZABLE ]
这与Jim Gray所提出的隔离级别有点差异。其中READ UNCOMMITTED即Jim的10(浏览);READ COMMITTED即20,游标稳定性;REPEATABLE READ为2.99990隔离(没有幻像保护);SERIALIZABLE隔离级别为30,完全隔离。SQL2标准默认为完全隔离(30)。各个级别存在问题如下:
隔离级 | 脏读 | 不可重复读 | 幻象读 |
读未提交 (Read uncommitted) | 可能 | 可能 | 可能 |
读提交 (Read committed) | 不可能 | 可能 | 可能 |
可重复读 (Repeatable read) | 不可能 | 不可能 | 可能 |
可串行化 (Serializable) | 不可能 | 不可能 | 不可能 |
MySQL 支持全部4个隔离级别,其默认级别为Repeatable read
My SQL常用目录及系统命令
1、数据库默认目录 /var/lib/mysql/,为啥放在这个地方?一般var下面是最大的目录,数据文件也存储在这个地方,如果要想修改数据文件目录,要配置文件进行修改,有几个地方要进行修改 (1)在配置文件中mysql.sock文件产生的位置,mysql.sock文件的产生位置,如socket = /home/data/mysql/mysql.sock (2)修改mysql的启动脚本中的datadir:init.d/myql:datadir=/home/data/mysql需要注意的有要将默认路径下的data文件copy到新目录而不是新建,还有要将Mysql的一份配置文件copy到/etc/下面,对sock位置的修改要在该文件下修改,最后在修改前停止mysql, 修改完进行生效重启Mysql.
2、配置文件 /usr/share/mysql(mysql.server命令及配置文件),如/usr/share/mysql/my-medium.cnf
3、相关命令 /usr/bin(mysql admin mysql dump等命令) 命令在/usr/bin下
4、启动脚本 /etc/rc.d/init.d/mysql(启动脚本文件mysql的目录)
5、自动启动:只要记住关于自动启动的都在/sbin/chkconfig就可以了
1)察看mysql是否在自动启动列表中 [root@test1local]# /sbin/chkconfig –list
2)把MySQL添加到系统启动服务组里面去 [root@test1local]# /sbin/chkconfig –add mysql
3)把MySQL从启动服务组里面删除。[root@test1 local]# /sbin/chkconfig –del mysql
6、停掉与启动Mysql命令:mysqladmin -u root -pshutdown 和 /etc/rc.d/init.d/mysql start
Sql命令中的几个关键字
(1) Group by使用, 比如delete from tablename where id not in (select max(id) from tablenamegroup by col1,col2,...) 《= 删除重复数据的例子, Group By的含义是进行分组值相同的为一组,注意使用Group By 之后 Select 出来的列必须只能来自于group By 或使用聚合函数Sum, AVG, max, min等中的列:返回集字段中,这些字段要么就要包含在Group By语句的后面,作为分组的依据;要么就要被包含在聚合函数中,GroupBy与聚合函数一块使用,表示对分组后的数据进行求和,平均,最大值等。
(2) Group By 和 Having, Where ,Order by语句的执行顺序:以尽可能的减少操纵的数据为原则,显然顺序为:Where, Group By, Having, Order by,首先where将最原始记录中不满足条件的记录筛选,减少分组数据,然后Group By与Having显然是Having是基于Groupby的,顾Having在Groupby之后,而Order By在Groupby和where之前都没用用,只有在Groupby之后才起作用,顾最后。
(3) Having 的使用:Having对Group By进行限定条件,可以使用聚合函数和Groupby中的列。
(4) Left outer join 与 left inner join的区别:外连接可以包含主表的全部行,而内连接只含有匹配那行
(5) Distinct 用法,去掉重复行,类似于Linux命令中的uniq,但uniq命令只能去掉相邻的重复行,所以在用之前要进行sort
(6) SQL Sever中用法: sysobjects和syscolumns表放了数据库中的所有表名和一个表的列名,而在My SQL中使用:show tables
(7) exists 和 in
select * from A
where id in(select id from B)
以上查询使用了in语句,in()只执行一次,它查出B表中的所有id字段并缓存起来.之后,检查A表的id是否与B表中的id相等,如果相等则将A表的记录加入结果集中,直到遍历完A表的所有记录.
它的查询过程类似于以下过程
List resultSet=[];
Array A=(select * from A);
Array B=(select id from B);
for(int i=0;i<A.length;i++) {
for(int j=0;j<B.length;j++) {
if(A[i].id==B[j].id) {
resultSet.add(A[i]);
break;
}
}
}
return resultSet;
可以看出,当B表数据较大时不适合使用in(),因为它会B表数据全部遍历一次.
如:A表有10000条记录,B表有1000000条记录,那么最多有可能遍历10000*1000000次,效率很差.
再如:A表有10000条记录,B表有100条记录,那么最多有可能遍历10000*100次,遍历次数大大减少,效率大大提升.
结论:in()适合B表比A表数据小的情况
select a.* from A a
where exists(select 1 from B b where a.id=b.id)
以上查询使用了exists语句,exists()会执行A.length次,它并不缓存exists()结果集,因为exists()结果集的内容并不重要,重要的是结果集中是否有记录,如果有则返回true,没有则返回false.
它的查询过程类似于以下过程
List resultSet=[];
Array A=(select * from A)
for(int i=0;i<A.length;i++) {
if(exists(A[i].id) { //执行select 1 from B b where b.id=a.id是否有记录返回
resultSet.add(A[i]);
}
}
return resultSet;
当B表比A表数据大时适合使用exists(),因为它没有那么遍历操作,只需要再执行一次查询就行.
如:A表有10000条记录,B表有1000000条记录,那么exists()会执行10000次去判断A表中的id是否与B表中的id相等.
如:A表有10000条记录,B表有100000000条记录,那么exists()还是执行10000次,因为它只执行A.length次,可见B表数据越多,越适合exists()发挥效果.
再如:A表有10000条记录,B表有100条记录,那么exists()还是执行10000次,还不如使用in()遍历10000*100次,因为in()是在内存里遍历比较,而exists()需要查询数据库,我们都知道查询数据库所消耗的性能更高,而内存比较很快.
结论:exists()适合B表比A表数据大的情况
当A表数据与B表数据一样大时,in与exists效率差不多,可任选一个使用.
MySql命令
(1) Mysql的所有用户都在user表中,可以通过该表进行,增加用户,修改用户密码,删除用户,和赋予用户权限等,注意修改后要使用FLUSH PRIVILEGES进行确认,如下:
删除匿名用户:delete from User where User=""; 匿名用户的User是空
增加一个用户 INSERT INTO mysql.user (Host,User,Password) VALUES ('%','system', PASSWORD('manager'));
修改密码update User set Password=PASSWORD(newpassword) where User=root;
(1) 用Grant 命令授权,输入的代码如下:
grant select,insert,update on mydb.*to NewUserName@HostNameidentified by"password"; 如果对HostName不限制,则使用%
(2) 对用户的每一项权限进行设置: 如:
mysql>INSERT INTO user VALUES('localhost','system',PASSWORD('manager'), 'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y'); 对于3.22.34版本的MySQL,这里共14个"Y",其相应的权限如下(按字段顺序排列):
权限
表列名称
相应解释
使用范围
select
Select_priv
只有在真正从一个表中检索时才需要select权限
表
insert
Insert_priv
允许您把新行插入到一个存在的表中
表
update
Update_priv
允许你用新值更新现存表中行的列
表
delete
Delete_priv
允许你删除满足条件的行
表
create
Create_priv
允许你创建新的数据库和表
数据库、表或索引
drop
Drop_priv
抛弃(删除)现存的数据库和表
数据库或表
reload
Reload_priv
允许您告诉服务器再读入授权表
服务器管理
shutdown
Shutdown_priv
可能被滥用(通过终止服务器拒绝为其他用户服务)
服务器管理
process
Process_priv
允许您察看当前执行的查询的普通文本,包括设定或改变口令查询
服务器管理
file
File_priv
权限可以被滥用在服务器上读取任何可读的文件到数据库表
服务器上文件存取
grant
Grant_priv
允许你把你自己拥有的那些权限授给其他的用户
数据库或表
references
References_priv
允许你打开和关闭记录文件
数据库或表
index
Index_priv
允许你创建或抛弃(删除)索引
表
alter
Alter_priv
允许您改变表格,可以用于通过重新命名表来推翻权限系统
表
对上面的14中权限,可以分为两种全局管理权限和数据表权限
全局管理权限:
FILE: 在MySQL服务器上读写文件。
PROCESS: 显示或杀死属于其它用户的服务线程。
RELOAD: 重载访问控制表,刷新日志等。
SHUTDOWN: 关闭MySQL服务。
数据库/数据表/数据列权限:
ALTER: 修改已存在的数据表(例如增加/删除列)和索引。
CREATE: 建立新的数据库或数据表。
DELETE: 删除表的记录。
DROP: 删除数据表或数据库。
INDEX: 建立或删除索引。
INSERT: 增加表的记录。
SELECT: 显示/搜索表的记录。
UPDATE: 修改表中已存在的记录。
特别的权限:
ALL: 允许做任何事(和root一样)。
USAGE: 只允许登录--其它什么也不允许做。
(2) 查看所有用show命令,查看当前用select函数
查看所有的数据库Show databases
创建和删除数据库create/drop database name
使用或连接数据库use databasename(),
查看当前使用的数据库:select database()
查询当前时间:selectnow()
查询当前用户:select user()
查询数据库版本:select version()
查看所有表:show tables
show processlist;列出每一笔联机的信息。
show variables;列出mysql的系统设定。
show tables from db_name;列出db_name中所有数据表;
show [full] columns from table_name;列出table_name中完整信息,如栏名、类型,包括字符集编码。
show index from table_name; 列出table_name中所有的索引。
show table status;;列出当前数据库中数据表的信息。
show table status from db_name;;列出当前db_name中数据表的信息。
alter table table_name engine innodb|myisam|memory ;更改表类型
explain table_name / describe table_name ; 列出table_name完整信息,如栏名、类型。
show create table table_name 显示当前表的建表语句
alter table table_name add primary key (picid) ; 向表中增加一个主键
alter table table_name add column userid int after picid 修改表结构增加一个新的字段
alter table table_name character set gb2312 改变表的编码
select user(); 显示当前用户。
select password(’root’); 显示当前用户密码
select now(); 显示当前日期
flush privileges 在不重启的情况下刷新用户权限
mysqld –default-character-set=gb2312 ;设置默认字符集为gb2312
(3) 表操作
备注:操作之前使用“use<数据库名>”应连接某个数据库。
匹配字符:可以用通配符_代表任何一个字符,%代表任何字符串;
联合字符或者多个列(将列id与":"和列name和"="连接)
select concat(id,':',name,'=') fromstudents;
limit(选出10到20条)<第一个记录集的编号是0>,SQLServer上为Top
select * from students order by id limit 9,10;
建表:create table <表名> (<字段名 1> <类型 1> [,..<字段名 n><类型 n>]);
插入数据:insert into <表名> [( <字段名 1>[,..<字段名 n >])] values ( 值 1 )[, ( 值 n )]
获取表结构:describe tablename, desc tablename, show columns from tablename
删除表 drop table tablename
删除表中数据 命令:delete from 表名 where 表达式
修改表中数据 命令:update 表名 set 字段=新值,... where 条件
在表中增加字段 命令:alter table 表名 add 字段 类型 其他;
更改表名 命令:rename table 原表名 to 新表名
更新字段内容 命令:update 表名 set 字段名 = 新内容,
删除student_course数据库中的students数据表:rm-f student_course/students.* 直接使
用linux命令来删除,也可以使用drop命令
创建临时表:create temporary table zengchao(name varchar(10));
创建表是先判断表是否存在: create table ifnot exists students(……);
从已经有的表中复制表的结构: create table table2 select * from table1 where 1<>1;
复制表,复制表的时候也会将表结构也复制过去了:create table table2 select * from table1;
对表重新命名:altertable table1 rename as table2;
创建索引,创建索引有两种方式,alter原来的表结构然后add,或者create index on
altertable table1 add index ind_id (id);
createindex ind_id on table1 (id);
createunique index ind_id on table1 (id);//建立唯一性索引
删除索引drop index idx_id on table1;
alter table table1 dropindex ind_id;
可以使用ALTER TABLE语句来更新与属性或表有关的约束。关于修改索引也是用类似的命令
删除约束:ALTER TABLEDROP CONSTRAINT约束名
增加约束ALTER TABLEADD CONSTRAINT约束名约束定义
(4) 数据库导入导出
从数据库导出数据库文件, 使用“mysqldump”命令
- 1)导出数据库: mysqldump -u [用户名] –p [数据库名] -A>[备份文件的保存路径],如
- mysqldump -h localhost -u root -p mydb >e:\MySQL\mydb.sql
- 2)导出数据和数据结构:mysqldump -u [用户名] -p [数据名 表名>[备份文件的保存路径]
- mysqldump -h localhost -u root -p mydb mytable>e:\MySQL\mytable.sql :数据表
- mysqldump -h localhost -u root -p mydb --add-drop-table >e:\MySQL\mydb_stru.sql:数据库结构
- 3)只导出数据不导出数据结构:mysqldump -u [用户名] -p -t [数据库名]>[备份文件的保存路径]
- 4)导出数据库中的Events: mysqldump -u [用户名] -p -E [数据库名]>[备份文件的保存路径]
- 5)导出数据库中的存储过程和函数:mysqldump -u [用户名] -p -R [数据库名]>[备份文件的保存路径]
从外部文件导入数据库中
- 1)使用“source”命令:source [备份文件的保存路径] 这个Source有点类似shell的source命令
- 2)使用“<”符号:mysql -u root –p < [备份文件的保存路径]
- 3)用文本方式将数据装入数据库表中(例如D:/mysql.txt)
- mysql> LOAD DATA LOCAL INFILE "D:/mysql.txt" INTO TABLE MYTABLE;
MySQL命令应用:
(1) mysql之删除重复数据,删除id重复的数据
delete person as a from person as a,
(
select *,min(id) from person group by id having count(1)> 1
) as b
where a.id = b.id
(2) 查找重复的,并且除掉最小的那个
delete tb_person as a from tb_person as a,
(
select *,min(id) from tb_person group by name having count(1) > 1
) as b
where a.name = b.name and a.id > b.id;
MySql explain优化SQL语句
在mysql version 4.1中,explain输出的结果格式改变了,使得它更适合例如 union语句、子查询以及派生表的结构。更令人注意的是,它新增了2个字段: id和 select_type。当你使用早于mysql4.1的版本就看不到这些字段了。
explain结果的每行记录显示了每个表的相关信息,每行记录都包含以下几个字段:
(1) id : 本次 select 的标识符。在查询中每个 select都有一个顺序的数值。
(2) select_type:select 的类型,可能会有以下几种:
- A. simple: 简单的 select (没有使用 union或子查询)
- B. primary: 最外层的 select。
- C. union: 第二层,在select 之后使用了 union。
- D. dependent union: union 语句中的第二个select,依赖于外部子查询
- E. subquery: 子查询中的第一个 select
- F. dependent subquery: 子查询中的第一个 subquery依赖于外部的子查询
- G. derived: 派生表 select(from子句中的子查询)
(3) table:记录查询引用的表。
(4) type:表连接类型。以下列出了各种不同类型的表连接,依次是从最好的到最差的:
- A. system: 表只有一行记录(等于系统表)。这是 const表连接类型的一个特例。
- B. const: 表中最多只有一行匹配的记录,它在查询一开始的时候就会被读取出来。由于只有一行记录,在余下的优化程序里该行记录的字段值可以被当作是一个恒定值。const表查询起来非常快,因为只要读取一次!const用于在和 primary key或unique索引中有固定值比较的情形。下面的几个查询中,tbl_name 就是 c表了:select * from tbl_name where primary_key=1; select * from tbl_name whereprimary_key_part1=1 and primary_key_part2=2;
- C. eq_ref: 从该表中会有一行记录被读取出来以和从前一个表中读取出来的记录做联合。与const类型不同的是,这是最好的连接类型。它用在索引所有部分都用于做连接并且这个索引是一个primary key或 unique类型。eq_ref可以用于在进行"="做比较时检索字段。比较的值可以是固定值或者是表达式,表达式中可以使用表里的字段,它们在读表之前已经准备好 了。以下的两个例子中,mysql使用了eq_ref 连接来处理 ref_table:(1)select * from ref_table,other_table where ref_table.key_column=other_table.column;(2)select * from ref_table,other_tablewhere ref_table.key_column_part1=other_table.column and ref_table.key_column_part2=1;
- D. ref: 该表中所有符合检索值的记录都会被取出来和从上一个表中取出来的记录作联合。ref用于连接程序使用键的最左前缀或者是该键不是 primary key或 unique索引(换句话说,就是连接程序无法根据键值只取得一条记录)的情况。当根据键值只查询到少数几条匹配的记录时,这就是一个不错的连接类型。ref还可以用于检索字段使用 =操作符来比较的时候。以下的几个例子中,mysql将使用 ref 来处理ref_table:(1) select * from ref_table wherekey_column=expr; (2) select * from ref_table,other_table where ref_table.key_column=other_table.column; (3) select * fromref_table,other_tablewhereref_table.key_column_part1=other_table.columnandref_table.key_column_part2=1;
- E. ref_or_null: 这种连接类型类似 ref,不同的是mysql会在检索的时候额外的搜索包含null值的记录。这种连接类型的优化是从mysql4.1.1开始的,它经常用于子查询。在以下的例子中,mysql使用ref_or_null 类型来处理 ref_table:select * from ref_table wherekey_column=expr or key_column is null;
- F. unique_subquery: 只是用来完全替换子查询的索引查找函数效率更高了,这种类型用例如一下形式的 in 子查询来替换ref:value in(select primary_key from single_table where some_expr)
- G. Index_subquery: 这种连接类型类似 unique_subquery。它用子查询来代替in,不过它用于在子查询中没有唯一索引的情况下,例如以下形式:value in (select key_column from single_table where some_expr)
- H. range: 只有在给定范围的记录才会被取出来,利用索引来取得一条记录。key字段表示使用了哪个索引。 key_len字段包括了使用的键的最长部分。这种类型时 ref 字段值是 null。range用于将某个字段和一个定植用以下任何操作符比较时 =, <>, >,>=,<, <=, is null, <=>, between, 或 in:select * from tbl_name where key_column = 10; select * fromtbl_namewhere key_column between 10 and 20; select * from tbl_namewhere key_column in(10,20,30); select * from tbl_name wherekey_part1= 10 and key_part2 in(10,20,30);
- I. index: 连接类型跟 all 一样,不同的是它只扫描索引树。它通常会比 all快点,因为索引文件通常比数据文件小。mysql在查询的字段知识单独的索引的一部分的情况下使用这种连接类型。
- J. all: 将对该表做全部扫描以和从前一个表中取得的记录作联合。这时候如果第一个表没有被标识为const的话就不大好了,在其他情况下通常是非常糟糕的。正常地,可以通过增加索引使得能从表中更快的取得记录以避免all。
(5) possible_keys:possible_keys字段是指 mysql在搜索表记录时可能使用哪个索引。注意,这个字段完全独立于explain 显示的表顺序。这就意味着 possible_keys里面所包含的索引可能在实际的使用中没用到。如果这个字段的值是null,就表示没有索引被用到。这种情况下,就可以检查 where子句中哪些字段那些字段适合增加索引以提高查询的性能。就这样,创建一下索引,然后再用explain 检查一下。想看表都有什么索引,可以通过 show index from tbl_name来看。
(6) key:key字段显示了mysql实际上要用的索引。当没有任何索引被用到的时候,这个字段的值就是null。想要让mysql强行使用或者忽略在 possible_keys字段中的索引列表,可以在查询语句中使用关键字force index,use index,或 ignore index。如果是 myisam 和 bdb 类型表,可以使用 analyzetable 来帮助分析使用使用哪个索引更好。如果是 myisam类型表,运行命令 myisamchk --analyze也是一样的效果。
(7) key_len:key_len 字段显示了mysql使用索引的长度。当 key 字段的值为 null时,索引的长度就是 null。注意,key_len的值可以告诉你在联合索引中mysql会真正使用了哪些索引。
(8) ref:ref 字段显示了哪些字段或者常量被用来和 key配合从表中查询记录出来。
(9) rows:rows 字段显示了mysql认为在查询中应该检索的记录数。
(10) extra:本字段显示了查询中mysql的附加信息。以下是这个字段的几个不同值的解释:
- A. distinct:mysql当找到当前记录的匹配联合结果的第一条记录之后,就不再搜索其他记录了。
- B. not exists:mysql在查询时做一个 left join优化时,当它在当前表中找到了和前一条记录符合 left join条件后,就不再搜索更多的记录了。下面是一个这种类型的查询例子:select * from t1left join t2 on t1.id=t2.id where t2.id is null; 假使 t2.id 定义为 not null。这种情况下,mysql将会扫描表 t1并且用 t1.id 的值在 t2 中查找记录。当在 t2中找到一条匹配的记录时,这就意味着 t2.id 肯定不会都是null,就不会再在 t2 中查找相同 id值的其他记录了。也可以这么说,对于 t1 中的每个记录,mysql只需要在t2 中做一次查找,而不管在 t2 中实际有多少匹配的记录。
- C. range checked for each record(index map: #) mysql没找到合适的可用的索引。取代的办法是,对于前一个表的每一个行连接,它会做一个检验以决定该使用哪个索引(如果有的话),并且使用这个索引来从表里取得记录。这个过程不会很快,但总比没有任何索引时做表连接来得快。
- D. using filesort: mysql需要额外的做一遍从而以排好的顺序取得记录。排序程序根据连接的类型遍历所有的记录,并且将所有符合 where条件的记录的要排序的键和指向记录的指针存储起来。这些键已经排完序了,对应的记录也会按照排好的顺序取出来。
- E. using index字段的信息直接从索引树中的信息取得,而不再去扫描实际的记录。这种策略用于查询时的字段是一个独立索引的一部分。
- F. using temporary: mysql需要创建临时表存储结果以完成查询。这种情况通常发生在查询时包含了groupby和 order by 子句,它以不同的方式列出了各个字段。
- G. using where,where子句将用来限制哪些记录匹配了下一个表或者发送给客户端。除非你特别地想要取得或者检查表种的所有记录,否则的话当查询的extra 字段值不是 usingwhere 并且表连接类型是 all 或 index时可能表示有问题。
- H. 如果你想要让查询尽可能的快,那么就应该注意 extra 字段的值为using filesort 和 using temporary 的情况。
使用explain优化SQL实例
通过 explain 的结果中 rows字段的值的乘积大概地知道本次连接表现如何。它可以粗略地告诉我们mysql在查询过程中会查询多少条记录。如果是使用系统变量 max_join_size 来取得查询结果,这个乘积还可以用来确定会执行哪些多表select 语句。下面的例子展示了如何通过 explain提供的信息来较大程度地优化多表联合查询的性能。假设有下面的 select 语句,正打算用 explain 来检测:
explain select tt.ticketnumber, tt.timein, tt.projectreference,tt.estimatedshipdate, tt.actualshipdate, tt.clientid,tt.servicecodes, tt.repetitiveid, tt.currentprocess,tt.currentdppers tt.recordvolume, tt.dpprinted, et.country,et_1.country, do.custname
from tt, et, et as et_1, do
where tt.submittime is null and tt.actualpc = et.employid and tt.assignedpc = et_1.employid and tt.clientid = do.custnmbr;
从from子句可以看出select子句要进行多表查询,要从三个表tt, et 和do三个表中进行联合查询,看起来是四个表
重点看where比较子句:tt.submittime is null and tt.actualpc = et.employid and tt.assignedpc =et_1.employid and tt.clientid = do.custnmbr;假设要比较的字段定义为表tt中的actualpc,actualpc 和clientid 均为 char(10)类型,et的employid 为char(15) 类型,do 的custnmbr为char(15) 类型,
这三个表的索引为tt有上那个索引:actualpc(值分布不均匀),assignedpc和clientid, et的为主键索引:employid (primary key),do表的也为主键索引custnmbr (primary key)
第一步,在任何优化措施未采取之前,经过 explain分析的结果显示如下:
table type possible_keys key key_len ref rows extra
et all primary null null null 74
do all primary null null null 2135
et_1 all primary null null null 74
tt all assignedpc null null null 3872 clientid, actualpc range checked for each record (key map: 35)
分析: 由于字段 type 的对于每个表值都是all,这个结果意味着mysql对所有的表做一个迪卡尔积;这就是说,每条记录的组合。这将需要花很长的时间,因为需要扫描每个表总 记录数乘积的总和。在这情况下,它的积是74 * 2135 * 74 *3872 = 45,268,558,720条记录。如果数据表更大的话,你可以想象一下需要多长的时间。
在这里有个问题是当字段定义一样的时候,mysql就可以在这些字段上更快的是用索引(对isam类型的表来说,除非字段定义完全一样,否则不会使用索 引)。在这个前提下,varchar和 char是一样的除非它们定义的长度不一致。由于 tt.actualpc 定义为char(10),et.employid 定义为 char(15),二者长度不一致。
为了解决这个问题,需要用 alter table 来加大 actualpc的长度从10到15个字符:altertable tt modify actualpc varchar(15); 现在 tt.actualpc 和 et.employid 都是 varchar(15),在执行一次explain:
table type possible_keys key key_len ref rows extra
tt all assignedpc, null null null 3872 using clientid, where actualpc
do all primary null null null 2135 range checked for each record (keymap: 1)
et_1 all primary null null null 74 range checked for eachrecord (key map: 1) et eq_ref primary primary 15 tt.actualpc 1
这还不够,它还可以做的更好:现在 rows值乘积已经少了74倍。这次查询需要用2秒钟。
第二个改变是消除在比较 tt.assignedpc = et_1.employid 和 tt.clientid= do.custnmbr 中字段的长度不一致问题:
altertable tt modify assignedpc varchar(15), ->modify clientid varchar(15);
table type possible_keys key key_len ref rows extra
et all primary null null null 74
tt ref assignedpc, actualpc 15 et.employid 52 using clientid, where actualpc
et_1 eq_ref primary primary 15 tt.assignedpc 1
do eq_ref primary primary 15 tt.clientid 1
这看起来已经是能做的最好的结果了。遗留下来的问题是,mysql默认地认为字段tt.actualpc的值是均匀分布的,然而表tt并非如此。幸好,我们可以很方便的让mysql分析索引的分布:mysql>analyze table tt; 到此为止,表连接已经优化的很完美了,explain 的结果如下:
table type possible_keys key key_len ref rows extra
tt all assignedpc null null null 3872 using clientid, where actualpc
et eq_ref primary primary 15 tt.actualpc 1
et_1 eq_ref primary primary 15 tt.assignedpc 1
do eq_ref primary primary 15 tt.clientid 1
请注意,explain 结果中的 rows字段的值也是mysql的连接优化程序大致猜测的,请检查这个值跟真实值是否基本一致。如果不是,可以通过在select 语句中使用 straight_join 来取得更好的性能,同时可以试着在from分句中用不同的次序列出各个表。
调整Mysql数据库性能:
- 改变索引缓冲区长度(key_buffer):一般,该变量控制缓冲区的长度在处理索引表(读/写操作)时使用。MySQL使用手册指出该变量可以不断增加以确保索引表的最佳性能,并推荐使用与系统内存25%的大小作为该变量的值。这是MySQL十分重要的配置变量之一,如果你对优化和提高系统性能有兴趣,可以从改变key_buffer_size变量的值开始。
- 改变表长(read_buffer_size):当一个查询不断地扫描某一个表,MySQL会为它分配一段内存缓冲区。read_buffer_size变量控制这一缓冲区的大小。如果你认为连续扫描进行得太慢,可以通过增加该变量值以及内存缓冲区大小提高其性能。
- 设定打开表的数目的最大值(table_cache):该变量控制MySQL在任何时候打开表的最大数目,由此能控制服务器响应输入请求的能力。它跟max_connections变量密切相关,增加 table_cache值可使MySQL打开更多的表,就如增加max_connections值可增加连接数一样。当收到大量不同数据库及表的请求时,可以考虑改变这一值的大小。
- 对缓长查询设定一个时间限制(long_query_time):MySQL带有“慢查询日志”,它会自动地记录所有的在一个特定的时间范围内尚未结束的查询。这个日志对于跟踪那些低效率或者行为不端的查询以及寻找优化对象都非常有用。long_query_time变量控制这一最大时间限定,以秒为单位。
Mysql 优化表命令
AnalyzeTable MySQL 的Optimizer(优化元件)在优化SQL语句时,首先需要收集一些相关信息,其中就包括表的cardinality(可以翻译为“散列程度”),它表示某个索引对应的列包含多少个不同的值——如果cardinality大大少于数据的实际散列程度,那么索引就基本失效了。
我们可以使用SHOW INDEX语句来查看索引的散列程度:SHOWINDEX FROM PLAYERS;
TABLE KEY_NAME COLUMN_NAMECARDINALITY
------- -------- ----------- -----------
PLAYERS PRIMARYPLAYERNO 14
因为此时PLAYER表中不同的PLAYERNO数量远远多于14,索引基本失效。
下面我们通过Analyze Table语句来修复索引:
ANALYZE TABLE PLAYERS;
SHOW INDEX FROM PLAYERS;
结果是:
TABLE KEY_NAME COLUMN_NAMECARDINALITY
------- -------- ----------- -----------
PLAYERS PRIMARYPLAYERNO 1000
此时索引已经修复,查询效率大大提高。
需要注意的是,如果开启了binlog,那么Analyze Table的结果也会写入binlog,我们可以在analyze和table之间添加关键字local取消写入。
Checksum Table数据在传输时,可能会发生变化,也有可能因为其它原因损坏,为了保证数据的一致,我们可以计算checksum(校验值)。使用MyISAM引擎的表会把checksum存储起来,称为live checksum,当数据发生变化时,checksum会相应变化。在执行Checksum Table时,可以在最后指定选项qiuck或是extended;quick表示返回存储的checksum值,而extended会重新计算checksum,如果没有指定选项,则默认使用extended。
Optimize Table经常更新数据的磁盘需要整理碎片,数据库也是这样,Optimize Table语句对MyISAM和InnoDB类型的表都有效。如果表经常更新,就应当定期运行OptimizeTable语句,保证效率。与Analyze Table一样,Optimize Table也可以使用local来取消写入binlog。对于经常修改的表,容易产生碎片,使在查询数据库时必须读取更多的磁盘块,降低查询性能。具有可变长的表都存在磁盘碎片问题,这个问题对blob数据类型更为突出,因为其尺寸变化非常大。可以通过使用optimize table来整理碎片,保证数据库性能不下降,优化那些受碎片影响的数据表。 optimize table可以用于MyISAM和BDB类型的数据表。实际上任何碎片整理方法都是用mysqldump来转存数据表,然后使用转存后的文件并重新建数据表;
Check Table数据库经常可能遇到错误,譬如数据写入磁盘时发生错误,或是索引没有同步更新,或是数据库未关闭MySQL就停止了。遇到这些情况,数据就可能发生错误:Incorrectkey file for table: ' '. Try to repair it. 此时,我们可以使用Check Table语句来检查表及其对应的索引。譬如我们运行CHECKTABLE PLAYERS; 结果是
TABLE OP MSG_TYPE MSG_TEXT
-------------- ----- -------- --------
TENNIS.PLAYERS check status OK
MySQL会保存表最近一次检查的时间,每次运行check table都会存储这些信息:
执行
SELECT TABLE_NAME, CHECK_TIME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'PLAYERS'
AND TABLE_SCHEMA ='TENNIS'; /*TENNIS是数据库名*/
结果是
TABLE_NAME CHECK_TIME
---------- -------------------
PLAYERS 2006-08-2116:44:25
Check Table还可以指定其它选项:
UPGRADE:用来测试在更早版本的MySQL中建立的表是否与当前版本兼容。
QUICK:速度最快的选项,在检查各列的数据时,不会检查链接(link)的正确与否,如果没有遇到什么问题,可以使用这个选项。
FAST:只检查表是否正常关闭,如果在系统掉电之后没有遇到严重问题,可以使用这个选项。
CHANGED:只检查上次检查时间之后更新的数据。
MEDIUM:默认的选项,会检查索引文件和数据文件之间的链接正确性。
EXTENDED:最慢的选项,会进行全面的检查。
Repair Table 用于修复表,只对MyISAM和ARCHIVE类型的表有效。
这条语句同样可以指定选项:
QUICK:最快的选项,只修复索引树。
EXTENDED:最慢的选项,需要逐行重建索引。
USE_FRM:只有当MYI文件丢失时才使用这个选项,全面重建整个索引。
与Analyze Table一样,Repair Table也可以使用local来取消写入binlog。
参考: http://www.blogjava.net/persister/archive/2008/10/27/236813.html
http://www.cnblogs.com/younggun/articles/1719943.html
http://blog.csdn.net/alongken2005/article/details/6394016