目标
了解什么是优化
掌握优化查询的方法
掌握优化数据库结构的方法
掌握优化mysql服务器的方法
什么是优化
合理安排资源,调整系统参数使得mysql运行更快,更节省资源
优化是多方面的,包括查询、更新、服务器等
原则: 减少系统瓶颈,减少资源占用,增加系统的反应速度
数据库性能参数
使用 show status 语句查看mysql数据库的性能参数
* show status like 'value'
常用的参数: slow_queries 慢查询次数 com_(CRUD) 操作的次数 Uptime 上线时间
查询优化
1. explain
在mysql中可以使用explain查看sql的执行计划,用法: explain select * from tb_item,
explain 查询语句
参数说明:
id: select 识别码。这是select查询序号,不重要
select_type:表示SELECT语句的类型
1. SIMPLE 表示简单查询,其中不包含连接查询和子查询
2. PRIMARY 表示主查询 或者是 最外围的查询语句
3. UNION 表示连接查询union 后的查询 ,就像下面的历史表查询
explain select * from ( select * from red_packet union all select * from red_packet_his) m
UNION中的第二个或后面的SELECT语句,取决于外面的查询。
5. UNION RESULT
连接查询的结果
6. SUBQUERY
子查询中的第一个select语句
explain select * from red_packet where send_aip_no = (
select send_aip_no from red_packet where gain_type = '1'
)
7、 DEPENDENT SUBQUERY
子查询中的第1个SELECT语句,取决于外面的查询。
8、 DERIVED
SELECT (FROM 子句的子查询)
type:表示表的连接类型(重要)
以下的连接类型的顺序是从最佳到最差
1. system
表仅有一行,这是const类型的特例,平时不会出现,只是特例
2. const
数据表只有一行匹配到,查询速度很快,常用于主键索引或者唯一索引的查询,可以理解为const的查询是最优
3. eq_ref
mysql手册是这样说的:"对于每个来自于前面的表的行组合,从该表中读取一行。这可能是最好的联接类型,除了const类型。它用在一个索引的所有部分被联接使用并且索引是UNIQUE或PRIMARY KEY"。eq_ref可以用于使用=比较带索引的列。
select * from user_info,order_info where user_id = source_order;
也就是 连接查询中的连接语句中的列,用到了唯一索引或者是主键索引
4. ref
查询条件的索引既不是primary key 也不是 unique, ref 用于 = 或<或>操作符带索引的列
select * from user_info,order_info where user_num = source_order; 比如user_num是索引列,
这个查询的执行计划的type就是ref
5、 ref_or_null
该联接类型如同ref,但是添加了MySQL可以专门搜索包含NULL值的行。在解决子查询中经常使用该联接类型的优化。
上面这五种情况都是很理想的索引使用情况。
6、 index_merge
该联接类型表示使用了索引合并优化方法。在这种情况下,key列包含了使用的索引的清单,key_len包含了使用的索引的最长的关键元素。
7、 unique_subquery
该类型替换了下面形式的IN子查询的ref: value IN (SELECT primary_key FROM single_table WHERE some_expr)
unique_subquery是一个索引查找函数,可以完全替换子查询,效率更高。
8、 index_subquery
该联接类型类似于unique_subquery。可以替换IN子查询,但只适合下列形式的子查询中的非唯一索引: value IN (SELECT key_column FROM single_table WHERE some_expr)
9、 range
只检索给定范围的行,使用一个索引来选择行
10、index
该联接类型与ALL相同,除了只有索引树被扫描。这通常比ALL快,因为索引文件通常比数据文件小。
11、ALL
对于每个来自于先前的表的行组合,进行完整的表扫描。(全表扫描,性能最差)
possible_key
表示mysql能使用哪个索引在该表中找到行,如果改列为null,说明没有使用索引,可以对
该列创建索引提高性能。
key
显示mysql实际查询中使用到的索引,如果没有用到,显示为null
可以强制使用索引或忽略索引:
select * from tb_user ignore index(age) where age<10; ---强制忽略索引
select * from tb_user use index(age) where age<10; ---强制使用索引
key_len
显示mysql决定使用的键的长度,如果没有用到键,则是null
ref
显示使用哪个列或常数与key一起从表中选择行
rows
mysql执行时,扫描的行数
extra(显示mysql解决查询的详细信息)
该列包含MySQL解决查询的详细信息
–直接创建索引
CREATE INDEX index_name ON table(column(length))
–修改表结构的方式添加索引
ALTER TABLE table_name ADD INDEX index_name ON (column(length))
–创建表的时候同时创建索引
CREATE TABLE `table` (
`id` int(11) NOT NULL AUTO_INCREMENT ,
`title` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL ,
`time` int(10) NULL DEFAULT NULL ,
PRIMARY KEY (`id`),
INDEX index_name (title(length))
)
–删除索引
DROP INDEX index_name ON table
–创建唯一索引
CREATE UNIQUE INDEX indexName ON table(column(length))
–修改表结构
ALTER TABLE table_name ADD UNIQUE indexName ON (column(length))
–创建表的时候直接指定
CREATE TABLE `table` (
`id` int(11) NOT NULL AUTO_INCREMENT ,
`title` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL ,
`time` int(10) NULL DEFAULT NULL ,
PRIMARY KEY (`id`),
UNIQUE indexName (title(length))
);
–创建表的适合添加全文索引
CREATE TABLE `table` (
`id` int(11) NOT NULL AUTO_INCREMENT ,
`title` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL ,
`time` int(10) NULL DEFAULT NULL ,
PRIMARY KEY (`id`),
FULLTEXT (content)
);
–修改表结构添加全文索引
ALTER TABLE article ADD FULLTEXT index_content(content)
–直接创建索引
CREATE FULLTEXT INDEX index_content ON article(content)
假如索引列TYPE有5个键值,如果有1万条数据,那么 WHERE TYPE = 1将访问表中的2000个数据块。
再加上访问索引块,一共要访问大于200个的数据块。
如果全表扫描,假设10条数据一个数据块,那么只需访问1000个数据块,既然全表扫描访问的数据块
少一些,肯定就不会利用索引了