- 浏览: 400351 次
- 性别:
- 来自: 福州
文章分类
最新评论
-
生于菇乡:
GRANT CREATE ROUTINE,ALTER ROUT ...
mysql 存储过程权限相关 -
cocos:
[MYSQL] ERROR: cannot allocate ...
一次数据库升级过程 mysql5.0.78 到 5.1.57 -
cocos:
MySQL ERROR] Plugin 'InnoDB' in ...
一次数据库升级过程 mysql5.0.78 到 5.1.57 -
rjgcs123:
云集国内redis大佬的群正在招募各路redis朋友,不管你是 ...
redis 安装 配置解析 -
cocos:
mkfsmkfs -t 文件系统类型 /dev/设备名如要把/ ...
mount
第一章
myisam,可以基于blob和text的前500字节,创建索引
myisam 支持fulltext
延迟更新索引
(delay_key_write)
CREATE TABLE `table3` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(30) DEFAULT NULL,
`id2` INT(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MYISAM DEFAULT CHARSET=utf8 DELAY_KEY_WRITE = 1
ALTER TABLE table2 DELAY_KEY_WRITE = 1
只有myisam支持全文检索
第三章 索引方面
字段尽可能的小
尽量避免null,用0代替。但是对性能的提升很小,最后考虑,索引的列最好不适用null
mysql性能优化点记录
一、优化数据访问
查询性能低下的最基本原因就是访问了太多数据。一些查询不可避免的要筛选大量的数据,单这并不常见。大部分性能欠佳的查询都可以用减
少数据访问的方式进行修改。在分析性能欠佳的查询的时候,下面两个步骤比较有用:
1.应用程序是否在获取超过需要的数据。这通常是访问了过多的行或列。
2.mysql服务器是否分析了超过需要的行。
对于访问的数据行很大,而生成的结果中数据行很少,可以尝试修改。
1.使用覆盖索引,它存储了数据,所以存储引擎不会去完整的行。
2.更改架构,一个例子就是使用汇总表。
3.重写复杂的查询,让mysql的优化器可以优化的执行。
二、复杂查询和多个查询
1.把一个复杂的查询分解为多个简单的查询。(mysql一般的服务器,每秒钟可以处理50 000个查询)
2.
三、缩短查询
将一次处理大量数据的操作,分解为多个小操作。循环的方式每次处理一部分数据。一次删除不要超过10 000行(delete)
四、分解链接
把一个多表连接分解成多个单个查询,然后在应用程序里实现联接。
这样的优势
1.缓存效率高。
2.mysql,可以更有效的利用表锁,查询会锁住单个表较短时间。
3.应用程序进行联接可以更方便的拓展数据库,把不同表放在不同服务器上。
4.查询更高效。
5.可以减少多余的行访问,可以减少网络流量和内存消耗。
小结:在程序端进行联接的效率更高
1.可以缓存早期查询的大量数据。
2.使用了多个myisam表
3.数据分布在不同的服务器上。
4.对于大表使用in替换联接
5.一个连接引用了同一个表多次。
当你重建汇总和缓存表的时候,在操作的时候你常常需要它们的数据保持可见。你可以使用“shadow table”(影像表)来实现。当你已经创建它之后,你可以使用原子性的重命名来交换这些表。举个例子,如果
你需要重建my_summary,你能创建my_summary_new,填充数据,把它和真正的表作交换。
mysql> DROP TABLE IF EXISTS my_summary_new, my_summary_old;
mysql> CREATE TABLE my_summary_new LIKE my_summary;
-- populate my_summary_new as desired
mysql> RENAME TABLE my_summary TO my_summary_old, my_summary_new TO my_summary;
mysql执行查询的一般性过程
1.客户端发送查询到服务器
2.服务器检查查询缓存,
3.服务器解析,预处理和优化查询,生成执行计划。
4.执行引擎调用存储引擎api执行查询。
5.服务器将结果发送到客户端。
mysql客户端、服务器协议
1.协议是半双工的。mysql服务器在某个时间可以发送或者接受数据,单不能同时发送和接收。所有没有办法阶段消息。
2.客户端用一个数据包将查询发送到服务器,所以max_packet_size这个配置参数对于大查询很重要的原因。
3.客户端从服务器提取数据的时候是服务器产生数据的同时把它们“推”到客户端的,客户端只需要接收推出来的数据,无法告诉服务器停止
发送数据。
查询缓存
SELECT SQL_NO_CACHE * FROM ol_answerlog LIMIT 1000
SHOW STATUS LIKE 'last_query_cost'
关键字straight_join 强制执行引擎按照查询中表现的顺序来进行链接操作。
严格的说,mysql不回尝试减少读取的行数,它只会试着优化对页面的读取,但是行数可以大致显示查询的开销。
连接优化器试着产生最低开销的查询计划。在可能的时候,他会从单表计划开始,检查所有的可能的子树的组合。但是对n个表连接,需要检
查组合的数量就是n的阶乘,这个数量称为ie搜索空间, 它增长非常快,如果一个查询需要连接10个表,那么要检查的数量将是10!=36288000
当搜索空间非常巨大的时候优化耗费的时间就会非常长,这时候服务器就不回执行完整的分析,但表的数量超过optimizer_search_depth的值
时,它就会走捷径,比如执行所谓的 贪婪搜索。
SHOW TABLE STATUS FROM `servant_591up`WHERE ENGINE IS NOT NULL
AND NAME LIKE '%ol_ans%';
max min的优化
select min(id) from ol_user where username = 'dddd@dd.com'
(一)max 和 min 会扫描整张表。
mysql的主键都是按照升序排列的。
可以使用limit 改写查询,
select userid from ol_user where username='test@nd.com' limit 1
(二)对同一表进行select 和 update
mysql不允许对一个表进行update的时候进行select
update tb1 as out_table
set cnt = (select count(*) from tb1 as inner_table where inner_table.type = outer_table.type);
一个实现方式:衍生表,当成临时表来处理。
update tb1 inner join(
select type,count(*) as cnt
from tb1
group by type
)as der using(type)
set tb1.cnt = der.cnt;
(三、)优化特定类型的查询
1.count
count的作用 统计值的数量和统计行的数量
值是非空表达式(NOT NULL)
一个常见的错误就是在想统计行数的时候,在count的括号中放入列名,如果想知道结果的行数,应该总是使用COUNT(*),这可以清晰的说明意
图,并且得到好的性能。
2.MYISAM
只有在没有WHERE条件的时候COUNT(*)才是最快的,在有条件过滤的时候并不非常快。
3.简单优化
可以利用MYISAM对COUNT(*)的优化对已经有索引的一小部分做统计。
SELECT COUNT(*) FROM WORD.CITY WHERE ID>5;
优化为下面的语句
SELECT (SELECT COUNT(*) FROM CITY) - COUNT(*) FROM CITY WHEREID<=5;
这样的explain只扫描6行数据
使用一个查询统计同一列中不同值的数量。
select sum(if(color='blue',1,0)) as blue,sum(if(color='red',1,0)) as red from items;
下面是一个等价查询
select count(color='blue' or null) as blue,count(color='red' or null) as red from items;
(四)优化联接
1.确保on 或using使用的列上有索引。
通常只需要在联接中的第2个表上添加索引就可以。
2.确保group by或order by只引用一个表中的列。这样可以使用索引。
3.谨慎升级mysql
(五)优化子查询
对于子查询,尽可能的使用联接。
(五)优化group by和distinct
1.主要方式:索引
2.优化group by的策略:临时表或文件排序分组。
SQL_SMALL_RESULT : 强制使用临时表
SQL_BIG_RESULT :强制使用文件排序
通常对表的id进行分组会更加高效
可以使用SQL_MODE参数禁止SELECT中使用在group by中出现的列
子查询创建的临时表不支持索引。
所以要让子查询创建的临时表尽可能的小。
3.使用ROLL UP 优化GROUP BY
WITH ROLLUP
最好的方式是将WITH ROLLUP 放在应用程序里。
注意: Rollup 与 order by 相互排拆
(六)优化limit和offset
LIMIT 和ORDER BY 一块使用。
如果没有索引,就使用文件排序。
(七)优化SQL_CALC_FOUND_ROWS
这个地方很重要
一个技巧:在含有limit的查询中添加SQL_CALC_FOUND_ROWS,这样就可以知道没有limit的时候会返回多少行数据。服务器会预测将会发现多少
行数据。但是服务器并不能真正的做到,只是告诉服务器生成结果并丢掉结果中不需要的部分。而不是在得到需要的数据后就立即停止。这个
选项代价很高。
一个非常好的设计:
如果每页有20条结果,那么应该查询limit 21行数据,只显示20条,如果结果中有21行,那么就会有下一页。
另一种方式:就是提取并缓存大量数据,比如1000行,然后从缓存中获取后续页面的数据。
可以让程序知道一共有多少数据,少于1000,程序知道有多少页,如果大于1000,可以显示找到的结果超过1000个。
这两种都比重复产生完整的结果效率高。
如果以上两种都不可以使用,可以使用覆盖索引,使用单独的count(*)会更好
(八)优化联合 union
mysql总是使用临时表来执行union,无法做更多的优化
重要的是,一定要使用union all,除非真的是需要服务器消除重复的行,
否则mysql会使用distinct选项,来确保所有行数据的唯一性。
(九)查询优化提示
可以用一些提示控制优化器的行为,每个提示只影响当前查询。
1.HIGH_PRIORITY 和 LOW_PRIORITY
HIGH_PRIORITY 让mysql 将一个select语句放在其他的语句的前面,mysql将它放在队列的前面,而不是在队列中等待。可以用在insert语句中
。
low——priority正好相反,可以用在SELECT INSERT UPDATE REPLACE DELETE
这两个选项在表锁的存储过程中有效,在innerdb无效,在myisam要小心使用,严重影响性能,禁止并发插入。
2.delayed
用户insert delete
立即返回,放入缓冲当中,,无法使用LAST_ISNERT_ID()
3.STRAIGHT_JOIN
强制mysql按照查询中表出现的顺序来连接表。
出现在两个连接的表中间时,强制这两个表按照顺序连接。
用途:mysql没有选择更好的链接,或者优化器需要花费很长时间来确定连接顺序。
4.SQL_SMALL_RESULT SQL_BIGA_RESULT
用在group by 和distinct语句中的,如何使用临时表
SQL_SMALL_RESULT :结果很小,可以放在索引过的临时表中,
SQL_BIGA_RESULT:结果很大,最好使用磁盘上的临时表进行排序。
5.SQL_BUFFER_RESULT
将结果放在临时表中,并且要尽快释放掉表锁。
6.SQL_CACHE SQL_NO_CACHE
7.SQL_CALC_FOUND_ROWS
在limit自居计算完整的结果集,可以通过found_ROWS()来取得它的行数,
最好不使用这个提示、
8.FOR_ UPDATE 和 LOCK IN SHARE MODE
只有innodb支持,提示控制锁定,仅对行锁起作用。select语句中
9.USE INDEX 和 IGNORE INDEX 和 FORCE INDEX
控制索引的使用,在mysql5.1中,还有 FOR ORDER BY FOR GROUP BY
用途:告诉优化器表扫描比索引代价高很多,
重要的系统变量
Optimizer_search_depth
优化器检查执行计划的深度。
Optimizer_prune_level
根据检查的行数来决定跳过一些查询计划。
(九) 用户自定义变量
一些需要注意的问题:
会禁止缓存
不能用于文字常量和标识的地方(表名,列名,limit)
和连接有关,不能跨通信使用
如果使用连接池,会引起代码隔离
mysql 5.0大小写敏感
不能显示的声明类型,最好的方式给变量显示的一个初始值 0 0.0 ‘’,
用户自定义变量的类型是动态的,赋值的时候才会变化。
优化器有时候会把变量优化掉。
set @ont:=1; :=运算符的优先级,低于其他的,最好使用括号()。。 也可以使用=赋值,最好统一使用:=
未定义的变量不会引起语法错误,很容易犯错。
五、mysql高级特性
查询缓存命中率
Qcache_hits/(Qcache_his+Com_select) show status
1.缓存未命中原因
查询不可缓存,不确定函数。CURRENT_DATE,结果太大, Qcache_not_cached 会记录两种无法缓存的查询数量。
服务器以前从来没见过这个缓存。
查询结果被缓存过,但是服务器把它移除。
很多缓存失效。
2.很多缓存未命中,但是不能缓存的查询很少。
查询缓存未被激活。
服务器看到了以前未见过的查询
缓存失效。
A:如何对查询缓存进行维护调优
Query_cache_type
表示缓存是否被激活,on off demand,demand:只有sql_cache的查询才可以被缓存。
Query_cache_size
缓存的总内存,字节单位。1024的倍数,
Query_cache_min_res_unit
分配缓存块的最小值
Query_cache_limit
限制了mysql存储的最大结果。如果超过这个值,会丢掉已经缓存过的值,并增加Query_not_chched的值。如果是这样需要在查询上增
加QUERY_NO_CACHE
Query_cache_wlock_invalidate
是否缓存其他链接已经锁定了的表,默认off,
B:优化的一些法则
减少碎片
需要仔细选择Query_cache_min_res_unit,可以避免在查询缓存中造成大量的内存浪费。
最佳设置根据典型查询结果确定。可以使用内存(Queryc_cache_size - Query_free_memory)除以Query_queries_in_cache
得到查 询的平均大小。可以通过query_cache_limit的值来阻止缓存大结果。
可以检查Qcache_free_blocks来探测缓存中碎片的情况,显示缓存中有多少内存块出于free状态。如果Qcache_free_blocks
大致 等于Qcache_total_blocks/2,则说明碎片非常严重,如果Qcache_lowmen_prunes的值在增加并且有大量的
自由块,说明碎片导致查 询整 被从缓存中永久删除。
可以使用FLUSH QUERY CACHE命令移除碎片。会把所有的存储块向上移动,把自由块移动到底部。会阻止访问查询缓存,锁定
整个服务器,通常这个速度很快,不会移除缓存中的数据,
RESET QUERY CACHE会清除缓存数据。
提高缓存可用性。
如果没有碎片,但是命中率不高,应该给缓存分配较少的内存。
服务器清理查询的时候会Qcache_lowmen_prunes的值会增加,如果值增加的过快则说明:
1.如果自由块很多,碎片
2.如果自由块比较少,说明工作负载使用的内存超过所分配的内存。可以检查Qcache_free_memory知道未使用的内
存。
可以禁用缓存查看缓存是否真的有效果
query_cacha_size = 0,可以关闭缓存(query_cache_type 无法影响已经打开了的链接,也不会把内存归还给服务
器。)
5.1.5 innodb和查询缓存
6.2.2 myisam键缓存
SHOW VARIABLES LIKE 'key_buffer_size'
键缓冲区,myisam本身只缓存索引,没有数据。
应该让key_buffer_size占到保留内存的25-50%。但是对于mysql5.0,最大上限都是4G
但是可以创建多个命名键缓冲区。可以一次在内存中保存4G以上的数据。
key_buffer_1 key_buffer_2 都是1G
在配置文件增加两行
key_buffer_1.key_buffer_size = 1G
key_buffer_2.key_buffer_size = 1G
可以使用cache index 命令把表映射到缓存
也可以用下面的命令把表的索引保存到key_buffer_1
cache index t1,t2 in key_buffer_1
也可以使用load index把表的索引预加载到缓存中
load index into cache t1,t2;
缓存命中率
100-((Key_reads * 100) / Key_read_requests)
缓存使用百分比
100-((Key_blocks_unused * key_cache_block_size) * 100 / key_buffers_size)
innodb 可以使用裸设备
raw
myisam,可以基于blob和text的前500字节,创建索引
myisam 支持fulltext
延迟更新索引
(delay_key_write)
CREATE TABLE `table3` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(30) DEFAULT NULL,
`id2` INT(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MYISAM DEFAULT CHARSET=utf8 DELAY_KEY_WRITE = 1
ALTER TABLE table2 DELAY_KEY_WRITE = 1
只有myisam支持全文检索
第三章 索引方面
字段尽可能的小
尽量避免null,用0代替。但是对性能的提升很小,最后考虑,索引的列最好不适用null
mysql性能优化点记录
一、优化数据访问
查询性能低下的最基本原因就是访问了太多数据。一些查询不可避免的要筛选大量的数据,单这并不常见。大部分性能欠佳的查询都可以用减
少数据访问的方式进行修改。在分析性能欠佳的查询的时候,下面两个步骤比较有用:
1.应用程序是否在获取超过需要的数据。这通常是访问了过多的行或列。
2.mysql服务器是否分析了超过需要的行。
对于访问的数据行很大,而生成的结果中数据行很少,可以尝试修改。
1.使用覆盖索引,它存储了数据,所以存储引擎不会去完整的行。
2.更改架构,一个例子就是使用汇总表。
3.重写复杂的查询,让mysql的优化器可以优化的执行。
二、复杂查询和多个查询
1.把一个复杂的查询分解为多个简单的查询。(mysql一般的服务器,每秒钟可以处理50 000个查询)
2.
三、缩短查询
将一次处理大量数据的操作,分解为多个小操作。循环的方式每次处理一部分数据。一次删除不要超过10 000行(delete)
四、分解链接
把一个多表连接分解成多个单个查询,然后在应用程序里实现联接。
这样的优势
1.缓存效率高。
2.mysql,可以更有效的利用表锁,查询会锁住单个表较短时间。
3.应用程序进行联接可以更方便的拓展数据库,把不同表放在不同服务器上。
4.查询更高效。
5.可以减少多余的行访问,可以减少网络流量和内存消耗。
小结:在程序端进行联接的效率更高
1.可以缓存早期查询的大量数据。
2.使用了多个myisam表
3.数据分布在不同的服务器上。
4.对于大表使用in替换联接
5.一个连接引用了同一个表多次。
当你重建汇总和缓存表的时候,在操作的时候你常常需要它们的数据保持可见。你可以使用“shadow table”(影像表)来实现。当你已经创建它之后,你可以使用原子性的重命名来交换这些表。举个例子,如果
你需要重建my_summary,你能创建my_summary_new,填充数据,把它和真正的表作交换。
mysql> DROP TABLE IF EXISTS my_summary_new, my_summary_old;
mysql> CREATE TABLE my_summary_new LIKE my_summary;
-- populate my_summary_new as desired
mysql> RENAME TABLE my_summary TO my_summary_old, my_summary_new TO my_summary;
mysql执行查询的一般性过程
1.客户端发送查询到服务器
2.服务器检查查询缓存,
3.服务器解析,预处理和优化查询,生成执行计划。
4.执行引擎调用存储引擎api执行查询。
5.服务器将结果发送到客户端。
mysql客户端、服务器协议
1.协议是半双工的。mysql服务器在某个时间可以发送或者接受数据,单不能同时发送和接收。所有没有办法阶段消息。
2.客户端用一个数据包将查询发送到服务器,所以max_packet_size这个配置参数对于大查询很重要的原因。
3.客户端从服务器提取数据的时候是服务器产生数据的同时把它们“推”到客户端的,客户端只需要接收推出来的数据,无法告诉服务器停止
发送数据。
查询缓存
SELECT SQL_NO_CACHE * FROM ol_answerlog LIMIT 1000
SHOW STATUS LIKE 'last_query_cost'
关键字straight_join 强制执行引擎按照查询中表现的顺序来进行链接操作。
严格的说,mysql不回尝试减少读取的行数,它只会试着优化对页面的读取,但是行数可以大致显示查询的开销。
连接优化器试着产生最低开销的查询计划。在可能的时候,他会从单表计划开始,检查所有的可能的子树的组合。但是对n个表连接,需要检
查组合的数量就是n的阶乘,这个数量称为ie搜索空间, 它增长非常快,如果一个查询需要连接10个表,那么要检查的数量将是10!=36288000
当搜索空间非常巨大的时候优化耗费的时间就会非常长,这时候服务器就不回执行完整的分析,但表的数量超过optimizer_search_depth的值
时,它就会走捷径,比如执行所谓的 贪婪搜索。
SHOW TABLE STATUS FROM `servant_591up`WHERE ENGINE IS NOT NULL
AND NAME LIKE '%ol_ans%';
max min的优化
select min(id) from ol_user where username = 'dddd@dd.com'
(一)max 和 min 会扫描整张表。
mysql的主键都是按照升序排列的。
可以使用limit 改写查询,
select userid from ol_user where username='test@nd.com' limit 1
(二)对同一表进行select 和 update
mysql不允许对一个表进行update的时候进行select
update tb1 as out_table
set cnt = (select count(*) from tb1 as inner_table where inner_table.type = outer_table.type);
一个实现方式:衍生表,当成临时表来处理。
update tb1 inner join(
select type,count(*) as cnt
from tb1
group by type
)as der using(type)
set tb1.cnt = der.cnt;
(三、)优化特定类型的查询
1.count
count的作用 统计值的数量和统计行的数量
值是非空表达式(NOT NULL)
一个常见的错误就是在想统计行数的时候,在count的括号中放入列名,如果想知道结果的行数,应该总是使用COUNT(*),这可以清晰的说明意
图,并且得到好的性能。
2.MYISAM
只有在没有WHERE条件的时候COUNT(*)才是最快的,在有条件过滤的时候并不非常快。
3.简单优化
可以利用MYISAM对COUNT(*)的优化对已经有索引的一小部分做统计。
SELECT COUNT(*) FROM WORD.CITY WHERE ID>5;
优化为下面的语句
SELECT (SELECT COUNT(*) FROM CITY) - COUNT(*) FROM CITY WHEREID<=5;
这样的explain只扫描6行数据
使用一个查询统计同一列中不同值的数量。
select sum(if(color='blue',1,0)) as blue,sum(if(color='red',1,0)) as red from items;
下面是一个等价查询
select count(color='blue' or null) as blue,count(color='red' or null) as red from items;
(四)优化联接
1.确保on 或using使用的列上有索引。
通常只需要在联接中的第2个表上添加索引就可以。
2.确保group by或order by只引用一个表中的列。这样可以使用索引。
3.谨慎升级mysql
(五)优化子查询
对于子查询,尽可能的使用联接。
(五)优化group by和distinct
1.主要方式:索引
2.优化group by的策略:临时表或文件排序分组。
SQL_SMALL_RESULT : 强制使用临时表
SQL_BIG_RESULT :强制使用文件排序
通常对表的id进行分组会更加高效
可以使用SQL_MODE参数禁止SELECT中使用在group by中出现的列
子查询创建的临时表不支持索引。
所以要让子查询创建的临时表尽可能的小。
3.使用ROLL UP 优化GROUP BY
WITH ROLLUP
最好的方式是将WITH ROLLUP 放在应用程序里。
注意: Rollup 与 order by 相互排拆
(六)优化limit和offset
LIMIT 和ORDER BY 一块使用。
如果没有索引,就使用文件排序。
(七)优化SQL_CALC_FOUND_ROWS
这个地方很重要
一个技巧:在含有limit的查询中添加SQL_CALC_FOUND_ROWS,这样就可以知道没有limit的时候会返回多少行数据。服务器会预测将会发现多少
行数据。但是服务器并不能真正的做到,只是告诉服务器生成结果并丢掉结果中不需要的部分。而不是在得到需要的数据后就立即停止。这个
选项代价很高。
一个非常好的设计:
如果每页有20条结果,那么应该查询limit 21行数据,只显示20条,如果结果中有21行,那么就会有下一页。
另一种方式:就是提取并缓存大量数据,比如1000行,然后从缓存中获取后续页面的数据。
可以让程序知道一共有多少数据,少于1000,程序知道有多少页,如果大于1000,可以显示找到的结果超过1000个。
这两种都比重复产生完整的结果效率高。
如果以上两种都不可以使用,可以使用覆盖索引,使用单独的count(*)会更好
(八)优化联合 union
mysql总是使用临时表来执行union,无法做更多的优化
重要的是,一定要使用union all,除非真的是需要服务器消除重复的行,
否则mysql会使用distinct选项,来确保所有行数据的唯一性。
(九)查询优化提示
可以用一些提示控制优化器的行为,每个提示只影响当前查询。
1.HIGH_PRIORITY 和 LOW_PRIORITY
HIGH_PRIORITY 让mysql 将一个select语句放在其他的语句的前面,mysql将它放在队列的前面,而不是在队列中等待。可以用在insert语句中
。
low——priority正好相反,可以用在SELECT INSERT UPDATE REPLACE DELETE
这两个选项在表锁的存储过程中有效,在innerdb无效,在myisam要小心使用,严重影响性能,禁止并发插入。
2.delayed
用户insert delete
立即返回,放入缓冲当中,,无法使用LAST_ISNERT_ID()
3.STRAIGHT_JOIN
强制mysql按照查询中表出现的顺序来连接表。
出现在两个连接的表中间时,强制这两个表按照顺序连接。
用途:mysql没有选择更好的链接,或者优化器需要花费很长时间来确定连接顺序。
4.SQL_SMALL_RESULT SQL_BIGA_RESULT
用在group by 和distinct语句中的,如何使用临时表
SQL_SMALL_RESULT :结果很小,可以放在索引过的临时表中,
SQL_BIGA_RESULT:结果很大,最好使用磁盘上的临时表进行排序。
5.SQL_BUFFER_RESULT
将结果放在临时表中,并且要尽快释放掉表锁。
6.SQL_CACHE SQL_NO_CACHE
7.SQL_CALC_FOUND_ROWS
在limit自居计算完整的结果集,可以通过found_ROWS()来取得它的行数,
最好不使用这个提示、
8.FOR_ UPDATE 和 LOCK IN SHARE MODE
只有innodb支持,提示控制锁定,仅对行锁起作用。select语句中
9.USE INDEX 和 IGNORE INDEX 和 FORCE INDEX
控制索引的使用,在mysql5.1中,还有 FOR ORDER BY FOR GROUP BY
用途:告诉优化器表扫描比索引代价高很多,
重要的系统变量
Optimizer_search_depth
优化器检查执行计划的深度。
Optimizer_prune_level
根据检查的行数来决定跳过一些查询计划。
(九) 用户自定义变量
一些需要注意的问题:
会禁止缓存
不能用于文字常量和标识的地方(表名,列名,limit)
和连接有关,不能跨通信使用
如果使用连接池,会引起代码隔离
mysql 5.0大小写敏感
不能显示的声明类型,最好的方式给变量显示的一个初始值 0 0.0 ‘’,
用户自定义变量的类型是动态的,赋值的时候才会变化。
优化器有时候会把变量优化掉。
set @ont:=1; :=运算符的优先级,低于其他的,最好使用括号()。。 也可以使用=赋值,最好统一使用:=
未定义的变量不会引起语法错误,很容易犯错。
五、mysql高级特性
查询缓存命中率
Qcache_hits/(Qcache_his+Com_select) show status
1.缓存未命中原因
查询不可缓存,不确定函数。CURRENT_DATE,结果太大, Qcache_not_cached 会记录两种无法缓存的查询数量。
服务器以前从来没见过这个缓存。
查询结果被缓存过,但是服务器把它移除。
很多缓存失效。
2.很多缓存未命中,但是不能缓存的查询很少。
查询缓存未被激活。
服务器看到了以前未见过的查询
缓存失效。
A:如何对查询缓存进行维护调优
Query_cache_type
表示缓存是否被激活,on off demand,demand:只有sql_cache的查询才可以被缓存。
Query_cache_size
缓存的总内存,字节单位。1024的倍数,
Query_cache_min_res_unit
分配缓存块的最小值
Query_cache_limit
限制了mysql存储的最大结果。如果超过这个值,会丢掉已经缓存过的值,并增加Query_not_chched的值。如果是这样需要在查询上增
加QUERY_NO_CACHE
Query_cache_wlock_invalidate
是否缓存其他链接已经锁定了的表,默认off,
B:优化的一些法则
减少碎片
需要仔细选择Query_cache_min_res_unit,可以避免在查询缓存中造成大量的内存浪费。
最佳设置根据典型查询结果确定。可以使用内存(Queryc_cache_size - Query_free_memory)除以Query_queries_in_cache
得到查 询的平均大小。可以通过query_cache_limit的值来阻止缓存大结果。
可以检查Qcache_free_blocks来探测缓存中碎片的情况,显示缓存中有多少内存块出于free状态。如果Qcache_free_blocks
大致 等于Qcache_total_blocks/2,则说明碎片非常严重,如果Qcache_lowmen_prunes的值在增加并且有大量的
自由块,说明碎片导致查 询整 被从缓存中永久删除。
可以使用FLUSH QUERY CACHE命令移除碎片。会把所有的存储块向上移动,把自由块移动到底部。会阻止访问查询缓存,锁定
整个服务器,通常这个速度很快,不会移除缓存中的数据,
RESET QUERY CACHE会清除缓存数据。
提高缓存可用性。
如果没有碎片,但是命中率不高,应该给缓存分配较少的内存。
服务器清理查询的时候会Qcache_lowmen_prunes的值会增加,如果值增加的过快则说明:
1.如果自由块很多,碎片
2.如果自由块比较少,说明工作负载使用的内存超过所分配的内存。可以检查Qcache_free_memory知道未使用的内
存。
可以禁用缓存查看缓存是否真的有效果
query_cacha_size = 0,可以关闭缓存(query_cache_type 无法影响已经打开了的链接,也不会把内存归还给服务
器。)
5.1.5 innodb和查询缓存
6.2.2 myisam键缓存
SHOW VARIABLES LIKE 'key_buffer_size'
键缓冲区,myisam本身只缓存索引,没有数据。
应该让key_buffer_size占到保留内存的25-50%。但是对于mysql5.0,最大上限都是4G
但是可以创建多个命名键缓冲区。可以一次在内存中保存4G以上的数据。
key_buffer_1 key_buffer_2 都是1G
在配置文件增加两行
key_buffer_1.key_buffer_size = 1G
key_buffer_2.key_buffer_size = 1G
可以使用cache index 命令把表映射到缓存
也可以用下面的命令把表的索引保存到key_buffer_1
cache index t1,t2 in key_buffer_1
也可以使用load index把表的索引预加载到缓存中
load index into cache t1,t2;
缓存命中率
100-((Key_reads * 100) / Key_read_requests)
缓存使用百分比
100-((Key_blocks_unused * key_cache_block_size) * 100 / key_buffers_size)
innodb 可以使用裸设备
raw
发表评论
-
用SQL找出每种类型中时间最新的前N个数据组成的集合
2012-03-23 22:46 1534比如有文章表 Article(Id,Category ... -
mysql select 中的escape,转义
2011-10-17 16:57 3041SELECT * FROM tb1 WHERE varchar ... -
mysql 变量
2011-07-13 21:45 22681. 使用用户变量 可以清空MySQL 用 ... -
安装DBI组件。 Can't locate DBI.pm in @INC-mysql接口
2011-07-12 21:05 10723Can't locate DBI.pm in @INC ( ... -
mysql 排名
2011-07-08 11:21 1100SET @i=0; SELECT @i:=@i+1,user ... -
Linux下设置自动删除N天前备份
2011-07-06 21:00 1689find /data1/mysqldata/mysqlback ... -
修改数据库字符集
2011-07-05 13:08 1145ALTER DATABASE gongwuyuan_063 ... -
一个导数据的存储过程
2011-07-04 21:27 1294DELIMITER $$ USE `gongwuyu ... -
MySQL字符串函数:字符串截取
2011-07-04 20:08 1269MySQL 字符串截取函数:left(), right ... -
mysql 清理 binlog 二进制日志文件
2011-07-03 21:41 8772mysql> PURGE MASTER LOG ... -
xtrabackup
2011-07-03 21:21 18701. 下载 wget http://www.percona. ... -
MySQL的FLUSH句法
2011-07-03 19:14 2689MySQL的FLUSH句法(清除 ... -
mysql 存储过程权限相关
2011-06-30 01:43 73431.修改mysql 存储过程的definer 修改mysql. ... -
MySQL命令行的几个用法
2011-06-28 14:23 21641.使用\G按行垂直显示结果 如果一行很长,需要这行显示的话 ... -
MySQL命令行的几个用法
2011-06-28 14:17 1MySQL的客户端命令行工 ... -
mysql null
2011-06-20 20:22 1214mysql> select 0 is null, 0 ... -
External Locking skip-external-locking
2011-06-14 22:59 2129External locking is the use of ... -
innodb 日志文件异常引起innodb 启动失败
2011-06-14 22:13 15846innodb 日志文件异常引起innodb 启动失败 110 ... -
mysql innodb 引擎初始化错误
2011-06-14 22:06 3323错误日志: InnoDB: The InnoDB me ... -
mysql Incorrect integer value错误
2011-06-14 21:58 1759# Set the SQL mode to strict ...
相关推荐
MySQL性能优化是一个涵盖广泛的主题,涉及多个层面,包括SQL语句优化、索引优化、数据库表结构优化、系统级配置优化以及服务器硬件优化。以下是对这些方面进行详细说明: 1. **SQL语句优化** - **慢查询日志**:...
MySQL性能优化是数据库管理员和开发人员的关键技能,它涉及到如何有效地使用SQL语句...《MySQL性能优化中文手册》中的Chapter_7._Optimization.pdf章节,将会详细阐述这些知识点,帮助你成为真正的MySQL性能优化大师。
### MySQL性能优化知识点详解 #### 一、背景及目标 - **目的**:厦门游家公司(4399.com)为了提升员工技能水平,制定了这份MySQL性能优化教程,旨在为已有一定MySQL使用经验的工程师提供实战指导。 - **适用场景*...
MySQL性能优化是数据库管理中的关键环节,特别是在高并发场景下,优化MySQL的性能对于提升系统整体效率至关重要。本教程将深入探讨MySQL性能优化的各个方面,帮助你理解并实践有效的优化策略。 首先,我们来了解**...
MySQL 性能优化详解 MySQL 是目前使用最多的开源数据库,但是 MySQL 数据库的默认设置性能非常的差,仅仅是一个玩具数据库。因此,在产品中使用 MySQL 数据库必须进行必要的优化。优化是一个复杂的任务,本文描述 ...
总结来说,MySQL性能优化是一个系统工程,涵盖查询优化、数据库结构优化和服务器配置优化等多个层面。通过掌握这些优化手段,我们可以有效减少系统瓶颈,提高数据库响应速度,从而提升整个应用的性能。在实际操作中...
### MySQL性能优化教程知识点概述 #### 一、MySQL执行优化 **1.1 背景及目标** - **背景**: 针对已具备一定MySQL使用经验的工程师,特别是适用于高并发、海量数据处理的互联网环境。 - **目标**: 通过对MySQL性能...
MySQL性能优化诊断脚本是一种非常实用的工具,用于检测和分析MySQL数据库的性能问题。`tuning-primer.sh`就是这样一个脚本,它通过运行一系列的查询和检查,为数据库管理员提供有关系统性能的深入见解,并提出可能的...
MySQL性能优化与架构设计是数据库管理员和开发人员必须掌握的关键技能之一。MySQL作为一个广泛使用的开源关系型数据库管理系统,其性能优化对于提升应用的整体性能至关重要。本资料主要关注MySQL的架构理解、性能...
### MySQL性能优化详解 #### 一、什么是MySQL优化? MySQL优化是指通过合理安排资源和调整系统参数,使得MySQL运行得更快、更节省资源的过程。优化的目的在于减少系统瓶颈,降低资源消耗,提升系统的响应速度。 #...
以上这些知识点都是MySQL性能优化的重要组成部分。通过深入理解和实践,你可以显著提升数据库的运行效率,满足高并发、大数据量的应用需求。教学视频和配套笔记会是很好的学习资源,帮助你系统掌握这些概念和技术。
以下是关于MySQL性能优化的一些关键知识点: 1. **索引优化**:索引是提高查询速度的关键。了解如何创建和设计有效的索引,包括主键、唯一键和非唯一键,以及何时使用B-Tree、Hash或全文索引。合理使用复合索引,...
### MySQL性能优化关键知识点 #### 一、MySQL优化思路 MySQL优化主要分为三个层次:SQL语句优化、表结构优化以及服务器配置优化。 1. **SQL语句优化**: - **选择合适的索引**:确保查询时使用的字段被正确索引...
以下是一些关于MySQL性能优化的重要知识点: 1. **索引优化**:索引是提升查询速度的关键,合理创建主键、唯一索引和普通索引可以大幅减少数据查找时间。避免在高基数列上建立索引,同时注意复合索引的顺序,通常应...
### MySQL性能优化之架构优化详解 #### 一、引言 在MySQL的性能优化中,架构优化是一项重要的工作。良好的数据库架构设计不仅能够提升系统的整体性能,还能够降低后续维护的成本。本文主要围绕数据索引及其对性能...