【转载】高性能MySQL小结
其实只看到了1/3,先记录一下,等以后有空了再补上。
将查询结果导出到文件
mysql > SQL QUERY INTO OUTFILE '/path/to/sql/file'
将每次操作都导出到文件
mysql > \T /path/to/file mysql > ... //这些操作,及操作的结果都会输出到对应的文件 mysql > \t
文件内容大概会是这样
(root@localhost) [(none)]> use noah; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed (root@localhost) [noah]> show tables; +----------------+ | Tables_in_noah | +----------------+ | blog_category | | blog_comment | | blog_post | | blog_res | | blog_role | | blog_role_res | | blog_role_user | | blog_tag | | blog_user | | test | +----------------+ 10 rows in set (0.00 sec) (root@localhost) [noah]> select * from test; +----+------+ | id | name | +----+------+ | 1 | foo | | 2 | bar | +----+------+ 2 rows in set (0.02 sec)
显示MySQL当前状态及其他信息
SHOW STATUS; //显示MySQL当前状态 SHOW VARIABLES; //显示MySQL的变量信息,如version/data_dir等等 SHOW VARIABLES LIKE '%home%'; //获取包含home的变量 SHOW TABLE STATUS\G //显示当前表的状态,注意后面的\G,垂直显示结果 DESCRIBE tbl; //获取表结构 SHOW FULL COLUMNS FROM tbl; //类似上面
显示MySQL当前的连接状况
# 使用mysqladmin mysqladmin processlist # 或进入到mysql cli后执行 mysql > show processlist; # 结果大概是这样 +-----+------+-----------+------+---------+------+-------+------------------+ | Id | User | Host | db | Command | Time | State | Info | +-----+------+-----------+------+---------+------+-------+------------------+ | 409 | root | localhost | noah | Query | 0 | NULL | show processlist | +-----+------+-----------+------+---------+------+-------+------------------+
关于TIMESTAMP
- 第一个TIMESTAMP字段会随着表其他字段的更新而自动更新,之后的TIMESTAMP字段则不会。
- TIMESTAMP的范围是:1970-2037;而DATETIME的范围是:1000-9999
移除重复的行
# 注意这个IGNORE参数,如果没加的话会报错,且执行失败 # 假设要去除a,b项重复的行 ALTER IGNORE TABLE tbl ADD UNIQUE INDEX(a,b);
查看当前在操作的数据库
SELECT DATABASE();
也可以在mysql的提示符上动点手脚
# edit /etc/mysql/my.cnf [mysql] #no-auto-rehash # faster start of mysql but no tab completition prompt=(\\u@\\h) [\\d]> \\
复制一个表
CREATE TABLE tbl1 LIKE tbl; INSERT INTO tbl1 SELECT * FROM tbl; # 也可以先用mysqladmin导出数据,再导入
定长表与变长表
包含任何varchar、text等变长字段的数据表,即为变长表,反之则为定长表。所以CHAR和VARCHAR不共存
CHAR,最多可以容纳30个字符,但如果字符数不到30个的话,也会占用这些空间,只不过会在后面补上空格,但我们查询时又会发现尾部没有空格,这是因为空格已经被CHAR处理掉了。
VARCHAR,也是最多可以容纳30个字符,但如果不足30个的话,有多少字符占多少空间,不会浪费。
变长表的优势在于有效利用空间,但由于记录大小不同,在其上进行许多删除或更新操作会使表中的碎片增多,需要定期OPTIMIZE TABLE以保持性能。
定长表的查询,检索和更新速度都比变长表快,但占用的空间也大。
PS:MySQL 5.0.3之后VARCHAR的最大字符数为65535
转换编码
SET NAMES utf8 # CHARSET utf8
聚合函数
COUNT [GROUP BY] COUNT + HAVING + GROUP BY (HAVING可以看作后置WHERE语句) MIN/MAX [GROUP BY] SUM/AVG [GROUP BY] DISTINCT [GROUP BY] 所有的这些聚合函数加上GROUP BY之后,都只对GROUP BY部分有效。(不好理解,忽略)
并发控制
读锁(共享锁)/写锁(排他锁)
当某一用户修改一部分数据时,MySQL会禁止其他用户读取同一数据。大多数时,MySQL都是以透明的方式实现锁的内部管理
锁粒度
只锁定部分修改的数据,而不是所有的资源,或者只对要修改的数据片精确加锁。任何时间,在给定的资源上,被加锁的数据量越小,就可以允许更多的并发修改,只要相互之间互不冲突即可
这么做的问题是加锁也会消耗系统资源。如获得锁,检查锁是否已解除,以及释放锁等,都会增加系统开销。如果系统花费大量时间来管理锁,而不是读/写数据,那么系统整体性能都可能会受到影响
所谓的锁策略,就是在锁开销和数据安全之间寻求一种平衡。
表锁(MyISAM)
开销最小,但不适合频繁写操作
行锁(InnoDb)
可以支持最大的并发处理,但同时也会增加开销(InnoDb),由存储引擎实现,而不是MySQL服务器
事务
一组原子性的SQL语句。要么全部执行(commit),要么全部不执行(rollback)
正像锁粒度的增加会导致锁开销的增加一样,这种事务处理中的额外安全措施,也会导致数据库服务器要完成更多的额外工作
MySQL默认操作是AutoCommit,这意味着除非显示地开始一个事务,否则将把每个SQL操作视为一个单独事务自动执行
死锁
两个或多个事务在同一资源上相互占用,并请求加锁时,导致的恶性循环现象
解决办法:死锁检测/死锁超时机制。InnoDb处理死锁的方法是,回滚拥有最少排他行级锁的事务。
隐式和显式锁定
InnoDb: 一个事务在执行过程中的任何时候,都可以获得锁,但只有在执行COMMIT或ROLLBACK语句后,才可以释放这些锁。
InnoDb也支持显式锁定,如:
SELECT ... LOCK IN SHARE MODE SELECT ... FOR UPDATE
多版本并发控制
MySQL事务性存储引擎,如InnoDb,不是简单使用行加锁机制,而是MVCC和行加锁机制关联使用。
MVCC不是MySQL独有的技术,其他如Oracle, Postgresql等都在使用
可以将MVCC设想成一种行级加锁的变形,它避免了很多情况下的锁操作,大大降低了系统的开销
MVCC是通过及时保存在某些时刻的数据快照,而得以实现的。
所谓"版本号",其实是InnoDb维护的一个计数器,每启动一个事务,计数器随着递增,并将该号作为事务的版本号
[INSERT]
InnoDb将系统当前的版本号设为新增行的版本号
[DELETE]
InnoDb将系统当前的版本号设为被删除行的删除号,该行并未立即被物理删除
[UPDATE]
INSERT+DELETE
[SELECT]
1. 行版本号不大于事务版本号。这确保了该行在事务开始时已存在,或者由当前事务创建、更新
2. 行删除号不存在,或者删除号大于事务版本号。这确保事务开始前行未被删除
对于被标记为删除的行,InnoDb有专门的线程负责物理删除,当行满足如下条件时认为可以将其物理删除:当前不存在版本号小于该行删除号的事务,这样可以确保不会有事务再引用到该行
保存这些额外记录的好处,是使大多数读操作都不必申请加锁
关于MyISAM
- 表加锁。并发低/开销少
- 将每个表存储成两个文件:数据文件(.MYD)和索引文件(.MYI)
- 使用CHECK TABLE mytable 和 REPAIR TABLE mytable来修复表,也可以使用myisamchk命令
- 索引长度不能超过1000(注意,如果是utf8的话,长度x3),InnoDb没有此限制
- 可以延迟索引。使用表创建选项DELAY_KEY_WRITE创建的MyISAM表,在SQL结束之后,不会将索引的改变数据写入磁盘,而是在内存的键缓冲区中缓存索引改变数据,只有在清理缓冲区或关闭表时才将索引块转到磁盘。对于数据经常改变,并且频繁使用的表,这种模式大大提高了表的处理性能。不过,如果服务器或系统崩溃,索引将肯定损坏,并需要修复
关于InnoDb
- 行级锁。并发高/开销相对高
- 高性能
- 崩溃后自动恢复
- 主键聚簇索引,辅助索引非聚簇索引(单独索引树),辅助索引也会包含主键列,所以如果主键列较大,则它的辅助索引也会较大
- 任何改变InnoDb表结构的操作会导致整个表的重建,包括重建所有索引
- 外键约束
- 自动提交性能差?
- 可以显示锁定
- 不要对InnoDb使用不带WHERE语句的count(*),这会导致InnoDb执行全表扫描或索引扫描,而MyISAM只需要从相关记录中读取该值即可。
性能检测
mysql > SET PROFILING = 1; mysql > ... mysql > SHOW PROFILES;
会把执行的语句和执行时间都打印出来,如下
+----------+------------+-----------------------------------+ | Query_ID | Duration | Query | +----------+------------+-----------------------------------+ | 1 | 0.00011700 | select count(*) from user | | 2 | 0.00033500 | select count(*) from user_copy | | 3 | 0.59868300 | select count(created) from user | | 4 | 0.51746400 | select count(name) from user_copy | | 5 | 0.00846700 | show table status like 'user' | +----------+------------+-----------------------------------+
还可以针对某个query进行更细致的分析
也可以使用FLUSH STATUS + SHOW SESSION STATUS
mysql > SHOW PROFILE FOR QUERY 1;
查询缓存
MySQL在第二次执行相同的SQL查询语句时,默认会使用查询缓存。加上"SQL_NO_CACHE"不使用查询缓存
SELECT SQL_NO_CACHE username, ...
关于NULL
- 尽量避免NULL
- MySQL难以优化引用了可空列的查询,它会使索引,索引统计和值更加复杂
- 即使要在表中存储"没有值"的字段,还是有可能不使用NULL的,考虑使用0或空字符来代替它。
索引
索引是性能问题的首要原因,先搞定索引,再去搞查询优化
B-Tree索引
- 根节点保存了指向子节点的指针,存储引擎根据指针寻找数据
- 当一个数据块不能放下所有索引字段数据时,就会形成树形的根节点或分支节点,所以树的深度和广度是由数据量决定的
- 每个节点包含了下层节点的链接,(没有相邻节点链接,上层链接可有可没有)
假设建立了一个(last_name, first_name, birth)的索引,此索引对于以下类型可用
匹配全名 (例如可以找到一个叫Cuba Allen,并且出生于1960-01-01的人)
匹配最左前缀 (例如可以找到姓为Allen的人,仅适用于索引中的第一列)
由于树的节点是排好序的,它们可以用于查找和ORDER BY查询
B-Tree的局限在于如果查询不是从索引列的最左边开始,就无法使用索引。所以索引列的顺序至关重要。
高性能索引策略
隔离列
如果在查询中没有隔离索引的列,MySQL通常不会是使用索引。"隔离"列意味着它不是表达式的一部分,也没有位于函数中。
前缀索引
找到合适的前缀长度(计算全列的选择性,并使前缀的选择性接近于它)
SELECT COUNT(DISTINCT city)/COUNT(*) FROM city_demo SELECT COUNT(DISTINCE LEFT(city, 4))/COUNT(*) FROM city_demo
也要注意如果数据分布非常不均匀,可能就会有问题
前缀索引能很好的减少索引的大小及提高速度,但MySQL不能在ORDER BY和GROUP BY中使用索引
聚集索引 (InnoDb)
当表有聚集索引时,它的数据行实际保存在索引的叶子页(而不是指针),所谓"聚集"就是指实际的数据行和相关的键值都保存在一起,每个表只能由一个聚集索引(主索引),因为不能以此把行保存在两个地方
优点:
- 可以把相关数据保存在一起。如果没有使用聚集,读取每个邮件都会访问磁盘
- 数据访问快。聚集索引把索引和数据都保存到了同一棵B-Tree中,因此从聚集索引中取得的数据通常比在非聚集索引进行查找要快
- 聚集索引能最大限度地提升I/O密集负载的性能。
缺点:
- 更新索引列代价是庞大的,因为它强制InnoDb把每个更新的行移到新位置
- 辅助索引会比较大,因为它们的叶子包含了被引用行的主键列
- 辅助索引访问需要两次索引查找
覆盖索引
所有满足查询需要的数据的索引(只需要读取索引,不需要再读取行数据),比如这条SQL语句
SELECT state_id, city, address FROM userinfo WHERE state_id = 5
如果只在state_id上建索引,则city,address都要从表里读取行数据
如果建立index (state_id, city, address),既能使用state_id索引,同时又可以使用覆盖索引,速度就快多了
多余和重复索引
- MySQL允许你在统一列上创建多个索引,所以MySQL不得不单独维护每一个索引
- 如果列(A,B)上有索引,那么另外一个列(A)上的索引就是多余的(B-Tree)
- 大多数情况下,多余索引都是不好的,为了避免它,应该扩展已有索引,而不是添加新索引
- 索引越多,更新索引的开销越大,尤其是在数据很多的情况下
--EOF--
若无特别说明,本站文章均为原创,转载请保留链接,谢谢
【转载】高性能MySQL小结相关推荐
- 《高性能MySQL》の复制
2019独角兽企业重金招聘Python工程师标准>>> 0x00前言 本书讲述到定稿前的MySQL5.5版,所以下面内容的适用范围止步于MySQL5.5.本文仅仅强调书中讲述的重中之 ...
- MySQL各种优化基于《高性能MySQL第三版》
[TOC] MySQL各种优化 查询优化 查询优化器模块 查询优化器的任务是发现执行 SQL 查询的最佳方案.大多数查询优化器,要么基于规则.要么基于成本. 大多数查询优化器,包含 MySQL 的查询 ...
- 高性能mysql主存架构
高性能mysql主存架构 MySQL Replication(Master与Slave基本原理及配置) 主从mysql工作原理: 1:过程: (1)Mysql的复制(replication)是一个异步 ...
- 读薄《高性能MySql》(四)查询性能优化
读薄<高性能MySql>(一)MySql基本知识 读薄<高性能MySql>(二)Scheme与数据优化 读薄<高性能MySql>(三)索引优化 读薄<高性能M ...
- 【转载】MySQL索引背后的数据结构及算法原理
本文转载自http://blog.jobbole.com/24006/ 摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储 ...
- 转-《高性能mysql》并不是一本好书——SQL笔记
转自: https://book.douban.com/review/8122660/ 版权归作者所有,任何形式转载请联系作者. 作者:姚泽源(来自豆瓣) 来源:https://book.douban ...
- (转载)mysql书籍
(转载)http://blog.csdn.net/symdfbb/article/details/7636332 MySQL技术内幕 mysql使用大全,可以说方方面面都包括了.认真研读大概一本就差不 ...
- 读薄《高性能MySql》(三)索引优化
读薄<高性能MySql>(一)MySql基本知识 读薄<高性能MySql>(二)Scheme与数据优化 读薄<高性能MySql>(三)索引优化 读薄<高性能M ...
- 高性能Mysql主从架构的复制原理及配置详解
1 复制概述 Mysql内建的复制功能是构建大型,高性能应用程序的基础.将Mysql的数据分布到多个系统上去,这种分布的机制,是通过将Mysql的某一台主机的数据复制到其它主机(slaves)上,并重 ...
最新文章
- 女程序员被阿里录取工资二万六,辞职时被领导挽留:给你四万留下
- uva12099 Bookcase ACM NWERC
- Druid 分析报表中的实战(二)
- Android中 广播发送 和 接受 的简单示例
- java中文件选择器JFileChooser的用法
- 在.net平台下,执行命令行
- 山西汾阳中学2021高考成绩查询,2021山西高考成绩查询时间
- ZOJ 2859 二维RMQ(模板)
- linux系统官方版下载 百度云,百度网盘linux版
- Hive窗口分析函数(案例详细讲解)
- 卸载并安装谷歌浏览器
- HTTP状态码404、413、500
- 计算机课程成绩认定管理办法,全日制普通本科生课程学分成绩对接认定管理办法...
- AMR文件结构解析——时长解析
- python3,烤地瓜案例
- 网站快照被劫持,网站被劫持跳转另一个网站解决办法
- rip路由协议java_路由协议之RIP
- webrtc QOS方法四.2(拥塞算法学习)
- Ubuntu18.04
- 一名合格的数据分析师,需要满足哪些条件