mysql数据库优化小结
2017-02-23 11:28
429 查看
一,sql语句的优化
1,任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。
2,对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
3,应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:
select id from t where num is null
可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:
select id from t where num=0
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,并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。或者查询结果占全表的20%以上时,也不会利用索引。
6,索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。
7,mySQL数据库Sql语句执行效率检查--Explain命令
Explain命令在解决数据库性能上是第一推荐使用命令,大部分的性能问题可以通过此命令来简单的解决,Explain可以用来查看SQL语句的执行效 果,可以帮助选择更好的索引和优化查询语句,写出更好的优化语句。
Explain语法:explain select … from … [where ...]
例如:explain select * from news;
输出:
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+
最关键的是possible_keys:列指出MySQL能使用哪个索引。
key:显示MySQL实际使用的键(索引)。如果没有选择索引,键是NULL
二,了解一下存储引擎
1,概念
关系数据库表是用于存储和组织信息的数据结构,可以将表理解为由行和列组成的表格,类似于Excel的电子表格的形式。有的表简单,有的表复杂,有的表根本不用来存储任何长期的数据,有的表读取时非常快,但是插入数据时去很差;而我们在实际开发过程中,就可能需要各种各样的表,不同的表,就意味着存储不同类型的数据,数据的处理上也会存在着差异,那么。对于MySQL来说,它提供了很多种类型的存储引擎,我们可以根据对数据处理的需求,选择不同的存储引擎,从而最大限度的利用MySQL强大的功能。这篇博文将总结和分析各个引擎的特点,以及适用场合,并不会纠结于更深层次的东西。我的学习方法是先学会用,懂得怎么用,再去知道到底是如何能用的。下面就对MySQL常见的存储引擎进行简单的介绍。
2,常见存储引擎
MyISAM
在mysql客户端中,使用以下命令可以查看MySQL支持的引擎。
代码如下:
show engines;
MyISAM表是独立于操作系统的,这说明可以轻松地将其从Windows服务器移植到Linux服务器;每当我们建立一个MyISAM引擎的表时,就会在本地磁盘上建立三个文件,文件名就是表明。例如,我建立了一个MyISAM引擎的tb_Demo表,那么就会生成以下三个文件:
1.tb_demo.frm,存储表定义;
2.tb_demo.MYD,存储数据;
3.tb_demo.MYI,存储索引。
MyISAM表无法处理事务,这就意味着有事务处理需求的表,不能使用MyISAM存储引擎。MyISAM存储引擎特别适合在以下几种情况下使用:
1.选择密集型的表。MyISAM存储引擎在筛选大量数据时非常迅速,这是它最突出的优点。
2.插入密集型的表。MyISAM的并发插入特性允许同时选择和插入数据。例如:MyISAM存储引擎很适合管理邮件或Web服务器日志数据。
InnoDB
InnoDB是一个健壮的事务型存储引擎,这种存储引擎已经被很多互联网公司使用,为用户操作非常大的数据存储提供了一个强大的解决方案。我的电脑上安装的MySQL 5.6.13版,InnoDB就是作为默认的存储引擎。InnoDB还引入了行级锁定和外键约束,在以下场合下,使用InnoDB是最理想的选择:
1.更新密集的表。InnoDB存储引擎特别适合处理多重并发的更新请求。
2.事务。InnoDB存储引擎是支持事务的标准MySQL存储引擎。
3.自动灾难恢复。与其它存储引擎不同,InnoDB表能够自动从灾难中恢复。
4.外键约束。MySQL支持外键的存储引擎只有InnoDB。
一般来说,如果需要事务支持,并且有较高的并发读取频率,InnoDB是不错的选择。
三,索引
官方介绍索引是帮助MySQL高效获取数据的数据结构。我的理解索引相当于一本书的目录,通过目录就知道要的资料在哪里,不用一页一页查阅找出需要的资料。关键字index。
索引的分类
1、主键索引
可以在建立表的添加
CREATE TABLE `class` (
`id` int(11) NOT NULL DEFAULT '0',
`classname` varchar(32) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
UNIQUE KEY `classname` (`classname`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
可以在建立完表之后,添加:alter table tablename add primary key(列1,列2)
例如:ALTER TABLE class ADD PRIMARY KEY (id)
主键索引的特点:
(1)一个表中最多只有一个主键索引
(2)一个主键索引可以指向多个列
(3)主键索引的列,不能有重复的值,也不能有null
(4)主键索引的效率高。
2、唯一索引
可以在建立表的时候添加:create table emp(name varchar(32) unique)
在建完表之后,添加:
alter table tablename add unique key [索引名](列名)
例如:ALTER TABLE class ADD UNIQUE KEY (classname)
唯一索引的特点:
(1)一个表中可以有多个唯一索引
(2)一个唯一索引可以指向多个列 ,
比如alter table tablename add unique [索引名](列1,列2)
(3)如果在唯一索引上,没有指定not null,则该列可以为空,同时可以有多个null,
(4)唯一索引的效率较高。
3、普通索引
使用普通索引主要是提高查询效率
添加alter table tablename add index [索引名](列1,列3)
4、全文索引
mysql自带的全文索引mysql5.5不支持中文,支持英文,同时要求表的存储引擎是myisam,InnoDB<
cdaf
/span>不支持,。如果希望支持中文,有两个方案,
(1)使用aphinx中文版coreseek (来替代全文索引)
(2)插件mysqlcft。
5、查看索引
(1)show index from 表名
(2)show indexes from 表名
(3)show keys from 表名
(4)desc 表名
6、删除索引
(1)主键索引的删除:
alter table tablename drop primary key;要注意:在删除主键索引时,要首先去掉auto_increment属性。
(2)唯一索引的删除
alter table tablename drop index 唯一索引的名字
(3)普通索引的删除:
alter table tablename drop index 普通索引的名字
四,索引的使用
1,最左前缀原则
对于创建的多列(复合)索引,只要查询条件使用了最左边的列,索引一般就会被使用,反之没有使用最左边的列,将不会使用索引。
2,对于使用like的查询,查询如果是”%XXX”,不会使用到索引,‘XXX%’会使用到索引。
3、如果条件中有or,则要求or的索引字段都必须有索引,否则不能用到索引。
该email添加索引后,在测试,会用到索引
4、如果列类型是字符串,一定要在条件中将数据使用引号引用起来,否则不使用索引。
5、优化group by语句
默认情况下, mysql对所有的group by col1,col2进行排序。这与在查询中指定order by col1,col2类型,如果查询中包括group by 但用户想要避免排序结果的消耗,则可以使用order by null禁止排序。
6、当取出的数据量超过表中数据的20%,优化器就不会使用索引,而是全表扫描。扫描的行数太多了,优化器认为全表扫描比索引来的块。
7、对应大批量插入数据
对于MyISAM:
先禁用索引:
alter table table_name disable keys;
loading data//insert语句; 执行插入语句
执行完成插入语句后,开启索引,统一添加索引。
alter table table_name enable keys;
对于Innodb:
1,将要导入的数据按照主键排序
2,setunique_checks=0,关闭唯一性校验。
3,setautocommit=0,关闭自动提交。
五,分区
就是把一个表存储到磁盘不同区域,仍然是一张表。
1、基本的概念:
mysql5.1后有4种分区类型:
(1)Range(范围)–这种模式允许将数据划分不同范围。例如可以将一个表通过年份划分成若干个分区。
(2)List(预定义列表)–这种模式允许系统通过预定义的列表的值来对数据进行分割
(3)Hash(哈希)–这中模式允许通过对表的一个或多个列的Hash Key进行计算,最后通过这个Hash码不同数值对应的数据区域进行分区。例如可以建立一个对表主键进行分区的表。
(4)Key(键值)-上面Hash模式的一种延伸,这里的Hash Key是MySQL系统产生的。
2 range分区:
假如你创建了一个如下的表,该表保存有20家超市的职员记录,这20家超市的编号从1到20.如果你想将其分成4个小分区,可以采用range分区,创建的数据表如下。
创建range分区语法:
create table emp( id int not null, namevarchar(32) not null default '' comment ‘职员的名称’, store_id int not null comment ‘超市的编号范围是1-20’ )engine myisam charset utf8 partition by range(store_id)( partition p0 values less than(6), //是store_id的值小于6的存储区域。 partition p1 values less than(11), //是store_id的值大于等于6小于11的存储区域。 partition p2 values less than(16), partition p3 values less than(21) ) insert into emp values(1,’哈哈’,1)--à数据是存储到p0区 insert into emp values(23,’呵呵呵’,15)--à数据是存储到p2区 insert into emp values(100,’嘻嘻嘻’,11)=à数据是存储到p2区。
测试使用取出数据时是否用到分区:
在取出数据时,条件中必须partitionby range(store_id),range里面的字段。
3、list分区与range分区有类似的地方
例子:假如你创建一个如下的一个表,该表保存有20家超市的职员记录,这20家超市的编号从1到20.而这20家超市分布在4个有经销权的地区,如下表所示:
create table emp( id int not null, name varchar(32) not null default '', store_id int not null ) partition by list(store_id)( partition p0 values in(5,6,7,8), partition p1 values in(11,3,12,11), partition p2 values in(16), partition p3 values in(21) )
注意:在使用分区时,where后面的字段必须是分区字段,才能使用到分区。
4、分区表的限制
(1)只能对数据表的整型列进行分区,或者数据列可以通过分区函数转化成整型列
(2)最大分区数目不能超过1024
(3)如果含有唯一索引或者主键,则分区列必须包含在所有的唯一索引或者主键在内
(4)按日期进行分区很非常适合,因为很多日期函数可以用。但是对于字符串来说合适的分区函数不太多 。
六,insert into 增强版
一、MySQL中的replace into
功能:
插入数据前,replace into会首先根据主键或唯一索引判断是否存在相同的记录,如果存在,则先删除原来数据,然后再插入新数据;如果没有相同的记录,则直接插入。
使用形式:
1. replace into table_name(col_name, ...) values(...)
2. replace into table_name(col_name, ...) select ...
3. replace into table_name set col_name=value, ...
前两种形式用的相对较多。其中 “into” 关键字可以省略,不过最好加上 “into”,这样意思更加直观。另外,对于那些没有给予值的列,MySQL将自动为这些列赋上默认值。
二、Oracle中的merge into
功能:
与mysql中的replace into类似,在插入数据前,merge into也会根据主键判断是否有相同的记录,不同的是后面的操作,merge into对于存在的相同记录可以不做任何操作,也可以进行修改操作,但是不能有其他操作;如果没有相同记录,可以不做任何操作,也可以做插入操作,同样也不能有其他操作。
使用形式:
MERGE INTO {table_a}
USING {table|views|query}
ON {condition}
WHEN MATCHED THEN UPDATE SET {clause}
WHEN NOT MATCHED THEN INSERT VALUES {clause}
例如:
--全部男生记录
create table fzq1 as select * from fzq where sex=1;
--全部女生记录
create table fzq2 as select * from fzq where sex=0;
/*涉及到两个表关联的例子*/
--更新表fzq1使得id相同的记录中chengji字段+1,并且更新name字段。
--如果id不相同,则插入到表fzq1中.
--将fzq1表中男生记录的成绩+1,女生插入到表fzq1中
merge into fzq1 aa --fzq1表是需要更新的表
using fzq bb -- 关联表
on (aa.id=bb.id) --关联条件
when matched then --匹配关联条件,作更新处理
update set
aa.chengji=bb.chengji+1,
aa.name=bb.name --此处只是说明可以同时更新多个字段。
when not matched then --不匹配关联条件,作插入处理。如果只是作更新,下面的语句可以省略。
insert values( bb.id, bb.name, bb.sex,bb.kecheng,bb.chengji);
六,group by having的应用
参考:
http://www.jb51.net/article/41975.htm
http://blog.csdn.net/bingogirl/article/details/52559302
相关文章推荐
- 利用 index、explain和profile优化mysql数据库查询小结
- mysql数据库优化小结
- 利用 index、explain和profile优化mysql数据库查询小结
- 优化mysql数据库小结
- mysql数据库优化小结
- mysql数据库优化小结
- MySQL数据库优化推荐的编译安装参数小结
- 优化mysql实验(explain;索引)+利用 index、explain和profile优化mysql数据库查询小结
- MySQL数据库优化推荐的编译安装参数小结
- MySQL数据库小结
- 架构设计:系统存储(9)——MySQL数据库性能优化(5)
- python 性能优化方法小结
- C6000系列C64X DSP EDMA/QDMA小结——数据传输和优化
- HBase在淘宝的应用和优化小结
- javascript性能优化小结
- apache2配置优化以及性能测试小结
- 浅谈MySQL数据库优化
- MySql数据库细节使用规范详细解读胜过千行代码优化
- Mysql数据库的优化