[转] MySQL索引原理及慢查询优化

2015-05-20 08:50:37 查看评论 850 人阅读    

MySQL凭借着出色的性能、低廉的成本、丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库。虽然性能出色,但所谓“好马配好鞍”,如何能够更好的使用它,已经成为开发工程师的必修课,我们经常会从职位描述上看到诸如“精通MySQL”、“SQL语句优化”、“了解数据库原理”等要求。我们知道一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,所以查询语句的优化显然是重中之重。
本人从13年7月份起,一直在美团核心业务系统部做慢查询的优化工作,共计十余个系统,累计解决和积累了上百个慢查询案例。随着业务的复杂性提升,遇到的问题千奇百怪,五花八门,匪夷所思。本文旨在以开发工程师的角度来解释数据库索引的原理和如何优化慢查询。

一个慢查询引发的思考

select
   count(*) 
from
   task 
where
   status=2 
   and operator_id=20839 
   and operate_time>1371169729 
   and operate_time<1371174603 
   and type=2;

系统使用者反应有一个功能越来越慢,于是工程师找到了上面的SQL。
并且兴致冲冲的找到了我,“这个SQL需要优化,给我把每个字段都加上索引”
我很惊讶,问道“为什么需要每个字段都加上索引?”
“把查询的字段都加上索引会更快”工程师信心满满
“这种情况完全可以建一个联合索引,因为是最左前缀匹配,所以operate_time需要放到最后,而且还需要把其他相关的查询都拿来,需要做一个综合评估。”
“联合索引?最左前缀匹配?综合评估?”工程师不禁陷入了沉思。
多数情况下,我们知道索引能够提高查询效率,但应该如何建立索引?索引的顺序如何?许多人却只知道大概。其实理解这些概念并不难,而且索引的原理远没有想象的那么复杂。

分类: MySQL 标签: mysql 索引 优化 慢查询

[转]Go 程序的性能调试问题

2015-03-30 06:10:13 查看评论 2327 人阅读    

假设你手上有个Go语言编写的程序,你打算提升它的性能。目前有一些工具可以为此提供帮助。这些工具能帮你发现包括CPU、IO和内存在内多种类型的热点。所谓热点,是指那些为了能显著提升性能而值得你去关注的地方。有时候这些工具还能帮助你发现程序中主要的性能瑕疵。举个例子,你没必要每次执行SQL查询前都对SQL语句进行参数化解析,你可以将这个准备过程在程序启动时一次完成。再举个例子,当前某个算法的复杂度是O(N²),但其实存在一个复杂度是O(N)的解决方案。为了能发现这些问题,需要理智地检查你在优化分析器中获取到的信息。比如上面提到的第一个问题,你会注意到相当长的时间被花费在了对SQL语句的准备上。

了解针对性能的不同边界因素也是比较重要的。比方说,如果一个程序使用100 Mbps带宽的网络进行通信,而目前已经占用了超过90 Mbps的带宽,为了提升它的性能,你拿这样的程序也没啥办法了。在磁盘IO、内存消耗和计算密集型任务方面,也有类似的边界因素。

将这点牢记在心,让我们看看有哪些工具可以用。

注意:这些工具会彼此互相影响。例如,对内存使用优化分析器会导致针对CPU的优化分析器产生误差,对goroutine阻塞使用优化分析器会影响调度器跟踪等等。为了获得更加精确的信息,请在隔离的环境中使用这些工具。

注意:本文描述的用法基于Go语言发布的1.3版。


CPU 分析器

Go 运行时包含了内建的CPU分析器,它用来展示某个函数耗费了多少CPU百分时间。这里有三种方式来使用它:

1. 最简单的是用"go test"的-cpuprofile选项。例如下面的命令:

$ go test -run=none -bench=ClientServerParallel4 -cpuprofile=cprof net/http

将会分析所给的基准并将结果写入"cprof"文件中。

然后:

$ go tool pprof --text http.test cprof

将会打印耗费最多CPU时间的函数列表。

这里有几种可用的输出形式,最实用的有 --text, --web 和 --list。运行 "go tool pprof" 来得到完整的列表。

这个选项最明显的缺点是它只能用来做测试。

2. net/http/pprof 包。这是网络服务器的理想解决方案。你可能仅仅需要导入net/http/pprof,然后使用下面的方法收集分析结果:

$ go tool pprof --text mybin http://myserver:6060:/debug/pprof/profile

3. 手动收集. 你需要导入 runtime/pprof 然后再main函数中添加下面的代码:

1   if *flagCpuprofile != "" {
2       f, err := os.Create(*flagCpuprofile)
3       if err != nil {
4           log.Fatal(err)
5       }
6       pprof.StartCPUProfile(f)
7       defer pprof.StopCPUProfile()
8   }

分析结果会被写入指定的文件中,像第一种方式一样使之可视化。

这里有一个使用 --web 选项来实现可视化的例子:

cpu profile


[转]DBA专家门诊一期:索引与sql优化问题汇总

2015-01-06 15:52:00 查看评论 1234 人阅读    

              这是从阿里云论坛上转载的一篇文章,是阿里大牛在论坛上解答问题的帖子汇总。


              非常感谢大家踊跃参加DBA专家门诊一期:索引与sql优化,很多云友都提出了己的问题,门诊主任医师玄惭对大家提的问题一一作了解答。现已整理好这些问题,分享在此,欢迎来拿,绝对干货! 篇幅较长,耐心细看! 
我们将赠送每位提问者每人一本凌云杂志第四期,请各位以论坛短消息形式将姓名、电话、地址发送给管理员xiaofanqie。
 
  
啊里新人(Q1):索引我一般都是只有主键,这玩意儿,是不是越少越好? 
玄惭(A1):在日常的业务开发中,常见使用到索引的地方大概有两类:  
第一类.做业务约束需求,比如需要保证表中每行的单个字段或者某几个组合字段是唯一的,则可以在表中创建唯一索引;  
比如:需要保证test表中插入user_id字段的值不能出现重复,则在设计表的时候,就可以在表中user_id字段上创建一个唯一索引:  
CREATE TABLE `test` (  
  `id` int(11) NOT NULL AUTO_INCREMENT,  
  `user_id` int(11) NOT NULL,  
  `gmt_create` datetime DEFAULT NULL,  
  PRIMARY KEY (`id`),  
  UNIQUE KEY `uk_userid` (`user_id`)  
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;  
 

分类: MySQL 标签: mysql 优化 索引