从CHAR(4)和VARCHAR(4)列检索的值并不总是相同,因为检索时从CHAR 列删除了尾部的空
格。通过下面的例子说明该差别:
mysql> CREATE TABLE vc (v VARCHAR(4), c CHAR(4));
Query OK, 0 rows affected (0.02 sec)
mysql> INSERT INTO vc VALUES ('ab ', 'ab ');
Query OK, 1 row affected (0.00 sec)
mysql> SELECT CONCAT(v, '+'), CONCAT(c, '+') FROM vc;
+----------------+----------------+
| CONCAT(v, '+') | CONCAT(c, '+') |
+----------------+----------------+
ab + | ab+ |
+----------------+----------------+
1 row in set (0.00 sec)
3.2.2 text 和blob
在使用text 和blob 字段类型时要注意以下几点,以便更好的发挥数据库的性能.
1. BLOB和TEXT值也会引起自己的一些问题,特别是执行了大量的删除或更新操作的时候。
删除这种值会在数据表中留下很大的"空洞",以后填入这些"空洞"的记录可能长度不
同,为了提高性能,建议定期使用OPTIMIZE TABLE 功能对这类表进行碎片整理.
2. 使用合成的(synthetic)索引。合成的索引列在某些时候是有用的。一种办法是根据其它的列的内容建立一个散列值,并把这个值存储在单独的数据列中。接下来你就可以通过检索散列值找到数据行了。但是,我们要注意这种技术只能用于精确匹配的查询(散列值对于类似<或>=等范围搜索操作符是没有用处的)。我们可以使用MD5()函数生成散列值,也可以使用SHA1()或CRC32(),或者使用自己的应用程序逻辑来计算散列值。请记住数值型散列值可以很高效率地存储。同样,如果散列算法生成的字符串带有尾部空格,就不要把它们存储在CHAR或VARCHAR列中,它们会受到尾部空格去除的影响。合成的散列索引对于那些BLOB或TEXT数据列特别有用。用散列标识符值查找的速度比搜索BLOB列本身的速度快很多。
3. 在不必要的时候避免检索大型的BLOB或TEXT值。例如,SELECT *查询就不是很好的想法,除非你能够确定作为约束条件的WHERE子句只会找到所需要的数据行。否则,你可能毫无目的地在网络上传输大量的值。这也是BLOB或TEXT标识符信息存储在合成的索引列中对我们有所帮助的例子。你可以搜索索引列,决定那些需要的数据行,然后从合格的数据行中检索BLOB或TEXT值。
4. 把BLOB或TEXT列分离到单独的表中。在某些环境中,如果把这些数据列移动到第二张数据表中,可以让你把原数据表中的数据列转换为固定长度的数据行格式,那么它就是有意义的。这会减少主表中的碎片,使你得到固定长度数据行的性能优势。它还使你在主数据表上运行SELECT *查询的时候不会通过网络传输大量的BLOB或TEXT值。
mysql的字符集包括字符集(CHARACTER)和校对规则(COLLATION)两个概念。字符集是用来定义mysql存储字符串的方式,校对规则则是定义了比较字符串的方式。字符集和校对规则是一对多的关系, MySQL支持30多种字符集的70多种校对规则。每个字符集至少对应一个校对规则。可以用SHOW COLLATION LIKE 'utf8%';命令查看相关字符集的校对规则。
4.4 怎样选择合适的字符集
我们建议在能够完全满足应用的前提下,尽量使用小的字符集。因为更小的字符集意味着能够节省空间、减少网络传输字节数,同时由于存储空间的较小间接的提高了系统的性能。有很多字符集可以保存汉字,比如utf8、gb2312、gbk、latin1 等等,但是常用的是gb2312 和gbk(所以为了减少网络传输或者减少IO,我们要选择gbk,by deven)。因为gb2312 字库比gbk 字库小,有些偏僻字(例如:洺)不能保存,因此在选择字符集的时候一定要权衡这些偏僻字在应用出现的几率以及造成的影响,不能做出肯定答复的话最好选用gbk。
4.5 Mysql 字符集的设置
mysql 的字符集和校对规则有4 个级别的默认设置:服务器级、数据库级、表级和字段级。分别在不同的地方设置,作用也不相同。服务器字符集和校对,在mysql 服务启动的时候确定。可以在my.cnf 中设置:
[mysqld]
default-character-set=utf8
或者在启动选项中指定:
mysqld --default-character-set=utf8
或者在编译的时候指定:
./configure --with-charset=utf8
如果没有特别的指定服务器字符集,默认使用latin1 作为服务器字符集。上面三种设置的方式都只指定了字符集,没有指定校对规则,这样是使用该字符集默认的校对规则,如果要使用该字符集的非默认校对规则,则需要在指定字符集的同时指定校对规则。可以用show variables like 'character_set_server';命令查询当前服务器的字符集和校对规则。
mysql的字符集包括字符集(CHARACTER)和校对规则(COLLATION)两个概念。字符集是用来定义mysql存储字符串的方式,校对规则则是定义了比较字符串的方式
5.1 Mysql 索引概述
还可以创建FULLTEXT 索引。该索引可以用于全文搜索。只有MyISAM 存储引擎支持FULLTEXT 索引,并且只为CHAR、VARCHAR 和TEXT 列。索引总是对整个列进行,不支持局部(前缀)索引。也可以为空间列类型创建索引。只有MyISAM 存储引擎支持空间类型。空间索引使用R-树。默认情况MEMORY(HEAP)存储引擎使用hash 索引,但也支持B-树索引。
5.2 设计索引的原则
1. 搜索的索引列,不一定是所要选择的列。换句话说,最适合索引的列是出现在WHERE 子句中的列,或连接子句中指定的列,而不是出现在SELECT 关键字后的选择列表中的列。
2. 使用惟一索引。考虑某列中值的分布。对于惟一值的列,索引的效果最好,而具有多个重复值的列,其索引效果最差。例如,存放年龄的列具有不同值,很容易区分各行。而用来记录性别的列,只含有“ M”和“F”,则对此列进行索引没有多大用处(不管搜索哪个值,都会得出大约一半的行)
3. 使用短索引。如果对串列进行索引,应该指定一个前缀长度,只要有可能就应该这样做。例如,如果有一个CHAR(200) 列,如果在前10 个或20 个字符内,多数值是惟一的,那么就不要对整个列进行索引。对前10 个或20 个字符进行索引能够节省大量索引空间,也可能会使查询更快。较小的索引涉及的磁盘I/O 较少,较短的值比较起来更快。更为重要的是,对于较短的键值,索引高速缓存中的块能容纳更多的键值,因此,MySQL也可以在内存中容纳更多的值。这增加了找到行而不用读取索引中较多块的可能性。(当然,应该利用一些常识。如仅用列值的第一个字符进行索引是不可能有多大好处的,因为这个索引中不会有许多不同的值。)
4. 利用最左前缀。在创建一个n 列的索引时,实际是创建了MySQL 可利用的n 个索引。多列索引可起几个索引的作用,因为可利用索引中最左边的列集来匹配行。这样的列集称为最左前缀。(这与索引一个列的前缀不同,索引一个列的前缀是利用该的前n 个字符作为索引值。)
5. 不要过度索引。不要以为索引“越多越好”,什么东西都用索引是错的。每个额外的索引都要占用额外的磁盘空间,并降低写操作的性能,这一点我们前面已经介绍过。在修改表的内容时,索引必须进行更新,有时可能需要重构,因此,索引越多,所花的时间越长。如果有一个索引很少利用或从不使用,那么会不必要地减缓表的修改速度。此外,MySQL 在生成一个执行计划时,要考虑各个索引,这也要费时间。创建多余的索引给查询优化带来了更多的工作。索引太多,也可能会使MySQL 选择不到所要使用的最好索引。只保持所需的索引有利于查询优化。如果想给已索引的表增加索引,应该考虑所要增加的索引是否是现有多列索引的最左索引。如果是,则就不要费力去增加这个索引了,因为已经有了。
6. 考虑在列上进行的比较类型。索引可用于“ <”、“ < = ”、“ = ”、“ > =”、“ >”和BETWEEN 运算。在模式具有一个直接量前缀时,索引也用于LIKE 运算。如果只将某个列用于其他类型的运算时(如STRCMP( )),对其进行索引没有价值。
5.3 btree 索引与hash 索引
对于BTREE 和HASH 索引,当使用=、<=>、IN、IS NULL 或者IS NOT NULL 操作符时,关键元素与常量值的比较关系对应一个范围条件。Hash 索引还有一些其它特征:它们只用于使用=或<=>操作符的等式比较(但很快)。优化器不能使用hash 索引来加速ORDER BY 操作。(该类索引不能用来按顺序搜索下一个条目)。MySQL 不能确定在两个值之间大约有多少行(这被范围优化器用来确定使用哪个索引)。如果你将一个MyISAM 表改为hash-索引的MEMORY表,会影响一些查询。只能使用整个关键字来搜索一行。(用B-树索引,任何关键字的最左面的前缀可用来找到行)。对于BTREE 索引,当使用>、<、>=、<=、BETWEEN、!=或者<>,或者LIKE 'pattern'(其中'pattern'不以通配符开始)操作符时,关键元素与常量值的比较关系对应一个范围条件。“常量值”系指:查询字符串中的常量、同一联接中的const 或system 表中的列、无关联子查询的结果、完全从前面类型的子表达式组成的表达式
下面是一些WHERE 子句中有范围条件的查询的例子:
下列范围查询适用于btree 索引和hash 索引
SELECT * FROM t1 WHERE key_col = 1 OR key_col IN (15,18,20);
下列范围查询适用于btree 索引
SELECT * FROM t1 WHERE key_col > 1 AND key_col < 10;
SELECT * FROM t1 WHERE key_col LIKE 'ab%' OR key_col BETWEEN 'bar' AND 'foo';
5.4 Mysql 如何使用索引
大多数MySQL 索引(PRIMARY KEY、UNIQUE、INDEX 和FULLTEXT)在B 树中存储。只是
空间列类型的索引使用R-树,并且MEMORY 表还支持hash 索引。
通过SHOW STATUS 可以提供服务器状态信息,也可以使用mysqladmin extendedstatus命令获得。SHOW STATUS 可以根据需要显示session 级别的统计结果和global级别的统计结果。
以下几个参数对Myisam 和Innodb 存储引擎都计数:
1. Com_select 执行select 操作的次数,一次查询只累加1;
2. Com_insert 执行insert 操作的次数,对于批量插入的insert 操作,只累加次;
3. Com_update 执行update 操作的次数;
4. Com_delete 执行delete 操作的次数;