一,优化的第一步是知道那条语句比较耗费时间是吧,用下面的语句进行查询吧
explain select count(*) from stu where name like "a%"\G
查询后的大概显示结果是这样的:
id: 1
select_type: SIMPLE //SIMPLE 表示select的类型
table: stu //输出结果集的表
type: range //表示表的连接类型
possible_keys: name,ind_stu_name //表查询时可能使用的索引
key: name //表示实际使用的索引
key_len: 50 //索引字段的长度
ref: NULL
rows: 8 //扫描行的数量,就这行最重要
Extra: Using where; Using index
1 row in set (0.00 sec)
知道了实际扫描了多少行,就可以选择不同的查询语句进行优化查询了,不是嘛?
查询时候需要注意的要点有:
1,要什么查什么,总是使用select * 不是个好习惯
2,查询比较时候保证类型一致会有助于提高速度
3,使用join来关联查询速度会快很多。
4,如果操作比较复杂,用事务机制也是个不错的选择。
5,如果怕事务操作影响表的查询,那使用锁定表既可以不影响查询,也可以在操作完成前保证不会有数据更改。
6,查询时候使用通配符通常会慢一点,对有索引的字段使用通配符查询,要类似于 like “a%”,而不要类似于 like "%a",因为通配符在字首会使索引也失去效果。
二,优化的最重要的步骤当然是建立索引了,建立索引后的速度和索引前的速度,用explain比较一下马上明了了,但是索引也不是随便加的,建立索引费时间,费空间,数据更改时候也相对较慢,因为索引也要跟着一起变才行。
建立索引的语句是这样的:
create index indexname on table(name(4));
索引需要注意的有:
1,在经常进行连接,但是没有指定为外键的列上建立索引,而不经常连接的字段则由优化器自动生成索引。
2,在频繁进行排序或分组(即进行group by或order by操作)的列上建立索引
3,在条件表达式中经常用到的不同值较多的列上建立检索,在不同值少的列上不要建立索引。
4, 如果待排序的列有多个,可以在这些列上建立复合索引(compound index)。
三,使用数据库的主从复制也可以有效避免服务器停止响应时造成的损失。而且更新不频繁的数据或者对实时性要求不高的数据可以通过从服务器查询来降低主数据服务器的压力。
1,给从服务器设置授权用户
mysql>grant all slave on *.* to [email protected] identified by "pass";
或
mysql>grant replication slave on *.* [email protected] identified by "pass";
2,修改主数据库服务器的配置文件my.cnf,开户binlog,并设置server-id的值
log-bin=mysql-bin
server-id=1
3,查看主服务器上当前的二进制日志名和偏移量值
mysql>show master status;
4,mysqldump备份主服务器数据,然后恢复到从服务器上去。
5,设置从服务器
server-id = 2 //从服务器id
master-host=192.168.10.1 //主服务器ip
master-user=user
master-password=pass
master-port=3306
log-bin=mysql-bin
#replicate-do-db=test
#replicate-do-table=test.t1
6,从启动从服务器,然后用show processlist \G查看主从复制进程,如果显示 state:waiting for master to send event,则表示连接成功。
四,剩下最重要的技术当然是分区技术了,把一个海量的数据表横向切成多个表,每个表查询起来就没有那么费劲了吧,而且对于应用层来说它还是一张表。mysql分区类型分五种:
RANGE分区:基于属于一个给定连续区间的列值,把多行分配给分区
LIST分区:类似于按RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合中的某个值来进行选择
HASH分区:基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算,这个函数可以包含MySQL中有效的、产生非负整数值的任何表达式
KEY分区:类似于按HASH分区,区别在于KEY分区只支持计算一列或多列,且MySQL服务器提供其自身的哈希函数
创建分区表的sql语句比较简单,前面建表语句与普通的是一样的,后面加上分区见表的语句,类似于这样:
CREATE TABLE part_tab ( c1 int default NULL, c2 varchar(30) default NULL, c3 date default NULL) engine=myisam
PARTITION BY RANGE (year(c3)) (
PARTITION p0 VALUES LESS THAN (1995),
PARTITION p1 VALUES LESS THAN (1996) , PARTITION p2 VALUES LESS THAN (1997) ,
PARTITION p3 VALUES LESS THAN (1998) , PARTITION p4 VALUES LESS THAN (1999) ,
PARTITION p5 VALUES LESS THAN (2000) , PARTITION p6 VALUES LESS THAN (2001) ,
PARTITION p11 VALUES LESS THAN MAXVALUE );
如果把partition by后面接list就是list类型分区表了。以此类推。怎么样很简单吧?
五,mysql增加缓存设置
[client]
……
default-character-set=gbk
default-storage-engine=MYISAM
max_connections=600
max_connect_errors=500
back_log=200
interactive_timeout=7200
query_cache_size=64M
……
table_cache=512
……
myisam_max_sort_file_size=100G
myisam_max_extra_sort_file_size=100G
myisam_sort_buffer_size=128M
key_buffer_size=1024M
read_buffer_size=512M
……
thread_concurrency=8