- 浏览: 84286 次
- 性别:
- 来自: 北京
文章分类
最新评论
原文出处:http://www.zwjoy.com/blog/?p=3
1. 商业需求
说明:
不合理的需求导致资源的投入与产出成反比,开发人员有必要对产品提出的需求进行评估,对不影响大局或者可有可无的功能与产品进行协商,商讨是否可以放弃该功能或者适当修改功能。
实例:
产品提出论坛帖子总数实时更新,当前论坛情况是用户量庞大,同时帖子更新频繁。如果要做到实时,必须每次发帖后同时更新统计表数据(假设统计数据全部存储在统计表里面)。如果一秒内帖子产生很多,由于并发问题导致统计数据并不正确,由于如果有锁资源争用,造成性能下降。
解决方案:
跟产品讨论数据其实可以不那么实时,没有哪个无聊的人会发完帖子,盯着论坛的帖子数研究总数是否增加,即时不准确也不会影响用户的实际操作。把实时功能去
掉后,可以做一个定时任务(SHELL或者用户触发皆可),系统每5分钟跑一次,更新掉论坛帖子数即可,这样最直接的结果是减少了大量由于更新产生的
query语句。
事实像类似DZ这样的开源项目都是不做实时的,甚至帖子的回复数都不是实时准确的,它是每发表一个回复,插入统计缓存,系统定时批量执行这些要更新的数据。
思考:
大家曾见过淘宝的分页,它并没有列出总共多少页,而是用户点击的附近几页,这样其实节省了select count(*) 的操作(innodb引擎做这个 跟myisam引擎做这个不在同一个概念,所以对于总数据庞大分页的东西其实可以修改分页方式,比如搜索结果)
PS:
无用功能堆积导致系统复杂
开发中经常会遇到做了的一些功能不需要啦,导致出现无用的代码和无用的数据表,应该在确认之后,及时对这些功能下线,可以备份一次数据即可
2. 系统架构
说明:
包括主从、读写分离、分布式散列存储、事务处理、引擎选用,存放数据、是否使用存储过程、视图、临时表、触发器等等
3. 数据表(schema)设计
Schema设计实质反映了一个项目的实际需求,是项目中的存储数据的一个体现,基本上我们看了数据表,大体知道这个项目在做什么。但在设计的同时需要考虑到基本业务逻辑所需要的QUERY操作以及由此产生的性能问题。
1) 适度冗余,减少JOIN操作
说明:
这个其实是反范式的操作,schema设计时不能完全遵照范式,范式的目的是减少冗余。 但适当的冗余对性能是有不少的提升。
实例:
记录论坛版块最后的发帖人以及发帖时间,这个可以通过在帖子表里面进行查询(select * from posts where pid = ‘’
order by dateline desc) , 但如果在版块表设计两个字段last_post_member last_post_time,
则可以减少查询次数,一次取出数据。虽然更新(对于频繁的更新,我们同样使用定时任务操作)要导致数据表的写操作,但相对更新,查询显然更加频繁。
2) 大表水平拆分
说明:
跟适当冗余相反,大表水平拆分则是根据表里面数据读取的频繁度将一张表分成多张。
实例:
大家见过许多开源项目,基本上用户数据存储在两张或者更多的表中,比如bbs_member (主表)
bbs_memberfields(从表),主表存储读写比较多的字段(一般都是定长字段,比如username、password、groups),而
从表存储的是读写相对少的字段(比如qq msn 以及存数容量比较大的数据,比如text类型的数据)
3) 合适的数据类型
说明:更小的数据类型让数据库以更小的空间存储相同的数据量,这样直接较少IO的消耗。 特别是对于要进行比较或者排序的字段应该选用更为迅速的字段类型,从而节省CPU的消耗。
4) 创建合适的索引(单独做一节介绍)
总结:
所以我们在表的设计的时候,需要考虑到我们有多大的用户量(包括一个较为长远的考虑),考虑哪些query执行得更加频繁,从而给出相应的优化方案。
4. 索引(index)设计
1)索引类型:
B-tree ()
Myisam 主键就是聚集索引
聚集索引(数据表的物理存储顺序和表的逻辑存储顺序一致)
非聚集索引:。。。
InnoDB表会包含一个聚集索引
一般是按照下面的规则来设定聚集索引的:
1,假如表包含PRIMARY KEY,InnoDB使用它作为聚集索引
2,假如表没有定义PRIMARY KEY,InnoDB将第一个只包含NOT NULL属性列的UNIQUE index作为主键并且将它设置为聚集索引
3,前两者都不满足的时候,mysql就增加一个隐藏的autocreament
HASH (仅仅memory和 ndb引擎支持)
full-text (仅仅myisam支持,并且只支持 char varchar text三种数据类型)
r-tree
2)索引用途:
# 提高数据表检索效率
# 降低数据排序成本(排序主要消耗cpu和内存, 对于分组操作同样是先排序后分组)
2)如何判定 是否建立索引:
# 只有在操作频繁的字段建立索引,绝不建不必要或者想当然的索引,这个在设计表的时候要能大致估计SQL要怎么写。
# 唯一性太差的字段不建立索引,基本上当一条QUERY返回的数据占15%以上就不适合建立索引(通常的像像性别这样的字段绝对不建立索引)
# 更新频繁的字段不建立索引。更新表数据的时候同时要更新索引数据,导致IO访问增大以及影响整个存储系统的消耗。(如果查询更新都较多的情况下,则要比较查询与更新的比例,当比例较大的时候,更新附带的成本是可以接受的)
3) 单键索引和联合索引
# 当where语句的过滤条件比较多的时候,考虑几个字段同时出现的频繁度,对频繁度出现较高的字段集建立联合索引。
# 联合索引的缺点是多个字段同时存在,更新可能性更高,索引存储长度也越大。但就查询角度来讲这个因为它过滤掉更多的数据,所以效率更高。同时比在多个字段 都建立单键索引效果好(因为mysql query optimizer需要将多个索引 index_merge 成本更高,有时候还会放弃其他索引)
# 联合索引左前缀原则
使用最左(leftmost)前缀。建立多列复合索引的时候,你实际上建立了MySQL可以使用的多个索引。复合索引可以作为多个索引使用,因为索引中
最左边的列集合都可以用于匹配数据行。这种列集合被称为”最左前缀”(它与索引某个列的前缀不同,那种索引把某个列的前面几个字符作为索引值)。
假设你在表的state、city和zip数据列上建立了复合索引。索引中的数据行按照state/city/zip次序排列,因此它们也会自动地
按照
state/city和state次序排列。这意味着,即使你在查询中只指定了state值,或者指定state和city值,MySQL也可以使用这个
索引。因此,这个索引可以被用于搜索如下所示的数据列组合:
state, city, zip
state, city
state
MySQL不能利用这个索引来搜索没有包含在最左前缀的内容。例如,如果你按照city 或zip来搜索,就不会使用到这个索引。如果你搜索给定的 state和具体的ZIP代码(索引的1和3列),该索引也是不能用于这种组合值的,尽管MySQL可以利用索引来查找匹配的state从而缩小搜索的范 围。
# 前缀索引(只使用某个字段前面部分内容作为索引键索引该字段)
4) MYSQL索引限制
# 索引键长度总和不超过1000字节
# BLOB TEXT类型列只创建前缀索引
# 不支持函数索引
# 使用(!= <> )的时候, mysql不支持索引
# 过滤字段使用了函数运算(如abs() ) 等,不支持索引
# join语句中JOIN字段类型不一致,不支持索引
# LIKE语句中以(‘%abc’)开始,不支持索引
# 非等值查询时,不支持HASH索引
5) JOIN语句优化
# 永远用小结果集驱动大结果集(资源消耗存在较大区别外),比如A B联查,
A过滤后 10rows
B过滤后 20rows
A作为驱动表,JOIN过滤则为10次
B作为驱动表,JOIN过滤则为20次
所以选择结果集小的作驱动表
# join字段优化,保证每次查询节省资源
6)ORDER BY、 GROUP BY、 DISTINCT优化
原理都需要进行排序,除对字段索引外,需要去掉不必要的返回字段,节省内存(排序的原则)
5. QUERY语句优化
优化10原则:
1)优化更需要的优化
说明:执行对系统影响更大的QUERY,一般指的是高并发,执行更加频繁的SQL)
2)定位优化对象性能瓶颈
3)明确优化目标
4)explain
5)profule
6)小结果集驱动大结果集
7)尽可能在索引中完成排序
8)只取自己需要的字段
9)仅仅使用最有效的过滤条件
10)尽可能避免复杂的JOIN和子查询
6. 实例分析
Demo1:过度弱化query造成性能消耗
Table1: users表(user_id, user_name, last_feed_time)
Table2: feeds表(feed_id, user_id, feed_data, dateline)
显然users表与feeds表是一对多的关系,现在要查询最近有动作的10个用户,同时在列表页要显示该用户最近24小时的动作。
解决方法1:
// 得到10个最近有动作的用户
$sql = ‘SELECT user_id, user_name
FROM users ORDER BY last_feed_time DESC limit 10’;
// PHP获得10条数据 $rs
// 循环query查询对应ID的最近三个动作
foreach($rs as $k=>$v) {
$sql = “SELECT feed_data
FROM feeds WHERE user_id = ‘{$v[‘user_id’]}’ AND dateline <’’ ORDER BY dateline DESC “;
}
解决方法2:
// 同第一步
// 查询10个用户最近24小时动作
$sql = “SELECT user_id, feed_data
FROM feeds WHERE user_id IN () AND dateline < ‘’ ORDER BY dateline DESC ”:
// 数组组装
总结:我们在开发中经常碰到一些二级栏目的列表页,但数据来自不同的数据表,通常的做法是循环里面执行query,殊不知这样增加了QUERY的次 数,而每次QUERY都需要MYSQL进行解析,在这种情况下,宁愿QUERY复杂点或者在程序端复杂点,保证性能。而从另一个理论来讲,这种情况属于弱 化了QUERY造成性能问题。
Demo2:过度依赖query造成性能消耗
Table1: users表(user_id, user_name)
Table2: user_profile表(user_id, profile_data)
Table3: users_group表(id, group_id, user_id, level)
现在要查询群组ID为1的群组成员信息以及群主的详细信息。
解决方法1:
// 一次查询所有信息
SELECT u.user_name, up.profile_data
FROM users_group ug LEFT JOIN users u ON ug.user_id = u.user_id LEFT JOIN users_profile up ON u.user_id = up.user_id
WHERE ug.group_id = ‘1’
解决方法2:
// 先查询群组下用户的基本信息
SELECT u.user_id, u.user_name,
FROM users_group ug LEFT JOIN users u ON ug.user_id = u.user_id
WHERE ug.group_id = ‘1’
// 查群主信息
SELECT *
FROM users_profile WHERE user_id = ‘’;
总结:与上例相反,这个DEMO操作是增加一个query减少不必要的访问(只需要群主的详细信息,而profile存储的是数据类型比较大的数据,这样操作减少的是IO的访问)
Demo3:小结果集驱动大结果集
Table1: users表(user_id, user_name, sex)
Table3: users_group表(id, group_id, user_id, level, join_time)
现在要查询某个群组下面(id = 1)用户的名称和性别,按加入时间倒序取100-120条的记录
解决方法1:
SELECT u.user_id, u.username, u.sex
FROM users_group ug LEFT JOIN users u ON ug.user_id = u.user_id
WHERE ug.group_id = ‘1’ ORDER BY ug.join_time DESC LIMIT 100,120;
解决方法2:
SELECT u.user_id, u.username, u.sex
FROM (
SELECT user_id
FROM user_group
WHERE user_group.group_id = 1
ORDER BY join_time DESC
LIMIT 100,20) ug, user
WHERE ug.user_id = user.user_id;
总结:方法1参与join操作的是全部user_group中group_id = 1的数据、而方法2 参与join操作的数据仅仅是过滤过的20条数据。所以SQL优化永远记住小结果集驱动大结果集,节省的是CPU和IO的消耗。
发表评论
-
MySQL分组排序
2012-01-11 23:22 1912在一个表中取出根据某个字段排序并根据另一个字段分组的若干 ... -
Mysql的Group By
2011-12-20 16:28 867Oracle和MSSQL中,SQL中有Group By查询时, ... -
mysql中select * for update
2011-12-07 18:12 4431转自:http://www.cnblogs.com/liang ... -
Mysql Explain详解
2011-10-22 19:39 926看过不少关于Mysql Explain的介绍,感觉这篇最为详尽 ... -
游标中嵌套有其他查询时要注意的问题
2011-09-06 20:35 1853有如下存储过程: BEGIN DECLARE as ... -
CentOS源码安装MySQL5.1.41
2011-05-20 22:28 3179#安装需要的库 yum -y install ncur ... -
mysql导入导出命令总结
2011-03-31 14:53 0导出 1.导出SQL语句 mysqldump ... -
Mysql存储过程优化——使用临时表代替游标
2011-01-24 14:13 10668Mysql游标在操作小数据量时比较方便,效率可观,但操作大数据 ... -
工作笔记--Mysql触发器使用示例
2010-12-23 12:04 995更新IDC_Device_Info表记录时,记录下修改的时间, ... -
工作笔记--MySQL在有索引和没有索引时插入删除数据的速率比较
2010-12-16 15:25 1814表结构如下: CREATE TABLE `tmp` ( ... -
[转]Mysql切割字符串
2010-11-22 11:57 5154# 函数:func_split_TotalLength D ... -
Mysql源码安装开启Federated Storage Engine
2010-11-15 21:29 5045网上有诸多介绍源码安装Mysql时开启Federated引擎的 ...
相关推荐
MySQL性能调优与架构设计MySQL性能调优与架构设计MySQL性能调优与架构设计MySQL性能调优与架构设计MySQL性能调优与架构设计MySQL性能调优与架构设计MySQL性能调优与架构设计MySQL性能调优与架构设计
"MySQL性能调优与架构设计.pdf" 本资源摘要信息是关于 MySQL 数据库软件的性能调优和架构设计的知识点。MySQL 是一个流行的开源数据库管理系统,具有简单高效可靠的特点,广泛应用于各个行业。以下是从给定的文件中...
MySQL性能调优与架构设计 PDF图书MySQL性能调优与架构设计 PDF图书
### MySQL性能调优与架构设计的关键知识点 #### 一、MySQL概述 - **MySQL Server简介** - **定义**: MySQL是由MySQL AB公司(现已被Oracle收购)开发的一款开放源代码的关系型数据库管理系统(RDBMS)。 - **特点*...
在《MySQL性能调优与架构设计》一书中,附录部分提供了一个名为“example”的数据库创建脚本。这个脚本是用于演示和学习如何构建一个简单的数据库结构,它包含了几个核心表,如event、group_message、group_message_...
### MySQL性能调优与架构设计的关键知识点 #### 一、MySQL概述 - **定义与特点**:MySQL是一款由MySQL AB公司开发(后被Sun Microsystems收购)的开源数据库管理系统,以其简单高效、可靠性强等特点著称。它是一款...
MySQL性能调优与架构设计是IT领域中一个关键的话题,特别是在大数据时代,高效稳定的数据库管理是企业业务的基础。本文将深入探讨如何优化MySQL的性能,以及如何设计高可用的数据库架构,以实现低成本且高性能的...
《MySQL性能调优与架构设计》是一本由简朝阳编著的专业书籍,专注于探讨如何提升MySQL数据库系统的性能并进行高效架构设计。这本书是扫描版,可能包含图像化的文本,适合电子阅读。 MySQL作为世界上最受欢迎的开源...
本书以 MySQL 数据库的基础及维护为切入点,重点介绍了 MySQL 数据库应用系统的性能调优,以及高可用可扩展的架构设计。 全书共分3篇,基础篇介绍了MySQL软件的基础知识、架构组成、存储引擎、安全管理及基本的备份...
《MySQL性能调优与架构设计》是简朝阳的一本专著,主要针对数据库管理员、开发人员和系统架构师,深入探讨了如何优化MySQL数据库的性能并进行合理的架构设计。书中涵盖了多个关键领域,旨在帮助读者提升数据库系统的...
### MySQL性能调优工具介绍与应用 MySQL作为全球最广泛使用的开源关系型数据库之一,在企业级应用中的地位不可动摇。为了确保MySQL能够高效稳定地运行,掌握一系列性能调优工具至关重要。本文将详细介绍多种MySQL...
MySQL是世界上最受欢迎的...本全册将详细讲解以上知识点,并通过实例演示如何在实际应用中实施这些策略,帮助读者成为MySQL性能调优与架构设计的专家。无论你是初学者还是有经验的DBA,都能从中获得宝贵的知识和经验。
本书“MySQL性能调优与架构设计高清全册”深入探讨了如何优化MySQL的性能并设计高效的数据架构,以满足大规模应用的需求。以下是对该书内容的详细解读: 1. **SQL基础与优化**:书中首先会讲解SQL语言的基本概念,...
### MySQL性能调优与架构设计 #### 一、MySQL Server简介 ##### 1.1 什么是MySQL MySQL是由MySQL AB公司(后来被Sun Microsystems收购,随后Sun又被Oracle收购)自主研发的一款开源数据库管理系统。它是一款支持...
MySQL性能调优参数 MySQL 是一个广泛使用的开源关系型数据库管理系统,在实际应用中,如何提高 MySQL 的性能是一个关键的问题。本文将总结 MySQL 性能调优参数,涵盖 Innodb 相关参数、连接参数、缓存参数、日志...
MySQL性能调优与架构设计是数据库管理领域中的一个重要主题,主要关注如何提升MySQL数据库的运行效率,优化查询性能,以及构建高效稳定的数据架构。简朝阳的这本书提供了详细的指南,包括了理论知识和实践技巧,旨在...
### MySQL性能调优与架构设计知识点概述 #### 一、MySQL基本介绍 ##### 1.1 MySQL Server简介 - **1.1.1 什么是MySQL** - MySQL是一款由MySQL AB公司开发的开源数据库管理系统,后来被Sun Microsystems收购。它是...
《MySQL性能调优与架构设计》是简朝阳先生的一部深度解析MySQL数据库性能优化与架构构建的专业著作。这本书深入探讨了MySQL在实际应用中的各种性能问题,并提供了有效的解决策略,同时对MySQL的架构设计进行了全面的...