http://blog.sina.com.cn/s/blog_438308750100im0b.html
我原来的公司是一家网络游戏公司,其中网站交易与游戏数据库结合通过ws实现的,但是交易记录存放在网站上,级别是千万级别的数据库是mysql数据库.
可能有人会问mysql是否支持千万级数据库,还有既然已经到了这个数据量公司肯定不差,为什么要用mysql而不用oracle这里我做一下解答
1. mysql绝对支持千万级数据库是可以肯定的,
2. 为什么选择择mysql呢?
1> 第一也是最主要的一条是mysql他能做到。
2>在第一点前提下以下的就不是太重要了,mysql相对操作简单,测试容易,配置优化也相对容易很多
3>我们这里的数据仅仅是为了记录交易保证交易是被记录的,对于查询的还是相对少只有管理后台操作中需要对数据库进行查询
4>数据结构简单,而且每条记录都非常小,因为查询速度不管和记录条数有关和数据文件大小也有直接关系.
5>我们采用的是大小表的解决办法,每天大概需要插入数据库好几百万条,这里可能还是有人怀疑,其实没问题,如果批量插入我测试的在普通的pc机子上带该一个线程并发我插入的是6千万条记录大概需要“JDBC插入6000W条数据用时:9999297ms”,小表保存最近插入的内容,把几天前的保存到大表中,这里我说的就是大表大概6-7千万条数据;
带着这些疑问和求知欲望咱们来做一个测试,因为在那个时候我也不是dba不知道人家是怎么搞的能够做成这么大的数据量,我们平时叶总探讨一些相关的内容
1.mysql的数据查询,大小字段要分开,这个还是有必要的,除非一点就是你查询的都是索引内容而不是表内容,比如只查询id等等
2.查询速度和索引有很大关系也就是索引的大小直接影响你的查询效果,但是查询条件一定要建立索引,这点上注意的是索引字段不能太多,太多索引文件就会很大那样搜索只能变慢,
3.查询指定的记录最好通过Id进行in查询来获得真实的数据.其实不是最好而是必须,也就是你应该先查询出复合的ID列表,通过in查询来获得数据
我们来做一个测试ipdatas表:
CREATE TABLE `ipdatas` (
`id` INT(11) NOT NULLAUTO_INCREMENT,
`uid` INT(8) NOT NULL DEFAULT'0',
`ipaddress` VARCHAR(50) NOTNULL,
`source` VARCHAR(255) DEFAULTNULL,
`track` VARCHAR(255) DEFAULTNULL,
`entrance` VARCHAR(255)DEFAULT NULL,
`createdtime` DATETIME NOTNULL DEFAULT '0000-00-00 00:00:00',
`createddate` DATE NOT NULLDEFAULT '0000-00-00',
PRIMARY KEY (`id`),
KEY `uid` (`uid`)
) ENGINE=MYISAM AUTO_INCREMENT=67086110 DEFAULTCHARSET=utf8;
这是我们做的广告联盟的推广ip数据记录表,由于我也不是mysql的DBA所以这里咱们仅仅是测试
因为原来里面有大概7015291条数据
这里我们通过jdbc的batch插入6000万条数据到此表当中“JDBC插入6000W条数据用时:9999297ms”;
大概用了两个多小时,这里面我用的是batch大小大概在1w多每次提交,还有一点是每次提交的数据都很小,而且这里用的myisam数据表,因为我需要知道mysql数据库的大小以及索引数据的大小结果是
ipdatas.MYD 3.99 GB (4,288,979,008 字节)
ipdatas.MYI 1.28 GB (1,377,600,512 字节)
这里面我要说的是如果真的是大数据如果时间需要索引还是最好改成数字字段,索引的大小和查询速度都比时间字段可观。
步入正题:
1.全表搜索
返回结构是67015297条数据
SELECT COUNT(id) FROMipdatas;
SELECT COUNT(uid) FROMipdatas;
SELECT COUNT(*) FROMipdatas;
首先这两个全表数据查询速度很快,mysql中包含数据字典应该保留了数据库中的最大条数
查询索引条件
SELECT COUNT(*) FROM ipdatasWHERE uid=1; 返回结果时间:2分31秒594
SELECT COUNT(id) FROM ipdatasWHERE uid=1; 返回结果时间:1分29秒609
SELECT COUNT(uid) FROM ipdatasWHERE uid=1; 返回结果时间:2分41秒813
第二次查询都比较快因为mysql中是有缓存区的所以增大缓存区的大小可以解决很多查询的优化,真可谓缓存无处不在啊在程序开发中也是层层都是缓存
查询数据
第一条开始查询
SELECT * FROM ipdatas ORDER BYid DESC LIMIT 1,10 ; 31毫秒
SELECT * FROM ipdatas LIMIT1,10 ; 15ms
第10000条开始查询
SELECT * FROM ipdatas ORDER BYid ASC LIMIT 10000,10 ; 266毫秒
SELECT * FROM ipdatas LIMIT10000,10 ; 16毫秒
第500万条开始查询
SELECT * FROM ipdatas LIMIT5000000,10 ;11.312秒
SELECT * FROM ipdatas ORDER BYid ASC LIMIT 5000000,10 ; 221.985秒
这两条返回结果完全一样,也就是mysql默认机制就是id正序然而时间却大相径庭
第5000万条开始查询
SELECT * FROM ipdatas LIMIT60000000,10 ;66.563秒 (对比下面的测试)
SELECT * FROM ipdatas ORDER BYid ASC LIMIT 50000000,10; 1060.000秒
SELECT * FROM ipdatas ORDER BYid DESC LIMIT 17015307,10; 434.937秒
第三条和第二条结果一样只是排序的方式不同但是用时却相差不少,看来这点还是不如很多的商业数据库,像oracle和sqlserver等都是中间不成两边还是没问题,看来mysql是开始行越向后越慢,这里看来可以不排序的就不要排序了性能差距巨大,相差了20多倍
查询数据返回ID列表
第一条开始查
select id from ipdatas orderby id asc limit 1,10; 31ms
SELECT id FROM ipdatas LIMIT1,10 ; 0ms
第10000条开始
SELECT id FROM ipdatas ORDERBY id ASC LIMIT 10000,10; 68ms
select id from ipdatas limit10000,10;0ms
第500万条开始查询
SELECT id FROM ipdatas LIMIT5000000,10; 1.750s
SELECT id FROM ipdatas ORDERBY id ASC LIMIT 5000000,10;14.328s
第6000万条记录开始查询
SELECT id FROM ipdatas LIMIT60000000,10; 116.406s
SELECT id FROM ipdatas ORDERBY id ASC LIMIT 60000000,10; 136.391s
select id from ipdataslimit 10000002,10; 29.032s
select id from ipdatas limit20000002,10; 24.594s
select id from ipdatas limit30000002,10; 24.812s
select id from ipdatas limit40000002,10; 28.750s 84.719s
select id from ipdatas limit50000002,10; 30.797s 108.042s
select id from ipdatas limit60000002,10; 133.012s 122.328s
select * from ipdatas limit10000002,10; 27.328s
select * from ipdatas limit20000002,10; 15.188s
select * from ipdatas limit30000002,10; 45.218s
select * from ipdatas limit40000002,10; 49.250s 50.531s
select * from ipdatas limit50000002,10; 73.297s 56.781s
select * from ipdatas limit60000002,10; 67.891s 75.141s
select id from ipdatasorder by id asc limit 10000002,10; 29.438s
select id from ipdatas orderby id asc limit 20000002,10; 24.719s
select id from ipdatas orderby id asc limit 30000002,10; 25.969s
select id from ipdatas orderby id asc limit 40000002,10; 29.860d
select id from ipdatas orderby id asc limit 50000002,10; 32.844s
select id from ipdatas orderby id asc limit 60000002,10; 34.047s
至于SELECT * ipdatas order byid asc 就不测试了 大概都在十几分钟左右
可见通过SELECT id不带排序的情况下差距不太大,加了排序差距巨大
下面看看这条语句
SELECT * FROM ipdatas WHERE idIN(10000,100000,500000,1000000,5000000,10000000,2000000,30000000,40000000,50000000,60000000,67015297);
耗时0.094ms
可见in在id上面的查询可以忽略不计毕竟是6000多万条记录,所以为什么很多lucene或solr搜索都返回id进行数据库重新获得数据就是因为这个,当然lucene/solr+mysql是一个不错的解决办法这个非常适合前端搜索技术,比如前端的分页搜索通过这个可以得到非常好的性能.还可以支持很好的分组搜索结果集,然后通过id获得数据记录的真实数据来显示效果真的不错,别说是千万级别就是上亿也没有问题,真是吐血推荐啊.
上面的内容还没有进行有条件的查询仅仅是一些关于orderby和limit的测试,请关注我的下一篇文件对于条件查询的1亿数据检索测试
最近做了个项目,实现对存在千万条记录的库表进行插入、查询操作。原以为对数据库的插入、查询是件很容易的事,可不知当数据达到百万甚至千万条级别的时候,这一切似乎变得相当困难。几经折腾,总算完成了任务。
1、 避免使用Hibernate框架
Hibernate用起来虽然方便,但对于海量数据的操作显得力不从心。
关于插入:
试过用Hibernate一次性进行5万条左右数据的插入,若ID使用sequence方式生成,Hibernate将分5万次从数据库取得5万个sequence,构造成相应对象后,再分五万次将数据保存到数据库。花了我十分钟时间。主要的时间不是花在插入上,而是花在5万次从数据库取sequence上,弄得我相当郁闷。虽然后来把ID生成方式改成increase解决了问题,但还是对那十分钟的等待心有余悸。
关于查询:
Hibernate对数据库查询的主要思想还是面向对象的,这将使许多我们不需要查询的数据占用了大量的系统资源(包括数据库资源和本地资源)。由于对Hibernate的偏爱,本着不抛弃、不放弃的作风,做了包括配SQL,改进SQL等等的相当多的尝试,可都以失败告终,不得不忍痛割爱了。
2、 写查询语句时,要把查询的字段一一列出
查询时不要使用类似select * from x_table的语句,要尽量使用select id,name from x_table,以避免查询出不需要的数据浪费资源。对于海量数据而言,一个字段所占用的资源和查询时间是相当可观的。
3、 减少不必要的查询条件
当我们在做查询时,常常是前台提交一个查询表单到后台,后台解析这个表单,而后进行查询操作。在我们解析表单时,为了方便起见,常常喜欢将一些不需要查询的条件用永真的条件来代替(如:select count(id) from x_table where name like ‘%’),其实这样的SQL对资源的浪费是相当可怕的。我试过对于同样的近一千万条记录的查询来说,使用select count(id) from x_table 进行表查询需要11秒,而使用select count(id) from x_table where name like ‘%’却花了33秒。
4、 避免在查询时使用表连接
在做海量数据查询时,应尽量避免表连接(特别是左、右连接),万不得已要进行表连接时,被连接的另一张表数据量一定不能太大,若连接的另一张表也是数万条的话,那估计可以考虑重新设计库表了,因为那需要等待的时间决不是正常用户所能忍受的。
5、 嵌套查询时,尽可能地在第一次select就把查询范围缩到最小
在有多个select嵌套查询的时候,应尽量在最内层就把所要查询的范围缩到最小,能分页的先分页。很多时候,就是这样简单地把分页放到内层查询里,对查询效率来说能形成质的变化。
就是这些了,希望对遇到类似问题的朋友们能有所帮助!
继续追问
更多回答
推荐两类C++大牛博客!一类是:国外牛人,一类是国内牛人!
先说国内的一些C++牛人:
陈皓
酷 壳 - CoolShell
不认为自己是牛人的牛人,现就职于阿里巴巴。程序员技术练级攻略这篇博文足以奠定其江湖地位。陈皓自称有技术焦虑症,所以博客更新频繁,内容大量涉及C++及一切劝人上进的观点和方法,也有不少网友的高质量投稿,涉及软件开发的方方面面。
陈硕
陈硕的Blog_陈硕_CSDN博客-c++,muduo,C++ 工程实践领域博主
他是北京师范大学硕士,擅长 C++ 多线程网络编程和实时分布式系统架构。编写了开源 C++ 网络库 muduo; 参与翻译了《代码大全(第二版)》和《C++ 编程规范(繁体版)》,整理了《C++ Primer 第4版评注版》;曾多次在各地技术大会演讲。《Linux 多线程服务端编程》作者。
刘未鹏
刘未鹏,84年生人,现就职于微软,Imperfect C++, Exceptional C++ Style译者,大学时对C++有极大的学习兴趣,曾与C++之父邮件往来,记录在另一个博客C++的卢浮宫上。据闻刘未鹏现忙于育儿与心理学,所以博客更新较慢,但以往博客含金量高,很值得一读。博客内容偏重于学习方法,纯技术的C++文章少些。
章文嵩
http://zh.linuxvirtualserver.org/
章文嵩是LVS开源软件创始人,曾是阿里巴巴副总裁、阿里云CTO,2016年5月25日加入滴滴出行,任高级副总裁、负责CTO线基础平台部兼工程技术委员会主席。他在架构大型系统、系统软件开发、Linux操作系统、网络和软件开发管理等方面拥有丰富经验。
2009年加入淘宝,任核心系统负责人,沉淀了CDN、TFS、Tair、Tengine、MySQL、JVM、Linux内核、图像搜索等技术和产品,很好的满足了淘宝的海量业务对基础核心软件的需求;2013年投身云计算事业,历任阿里云飞天二部负责人、阿里云CTO、阿里云首席科学家,负责ECS、RDS、OSS、CDN、SLB等云产品,为云计算打造了稳定、易用、低成本的云平台和组件。
云风
云风,1979年2月5日出生的他,真名吴云洋(Cloud),毕业于中南大学(中南工业大学机械自动化963班),思维敏锐,富有创造性,具有丰富的游戏策划和程序开发经验,尤其擅长汇编语言及程序优化。早期在cfido和水木清华BBS发表了多篇关于游戏制作的文章,后来制作了第一个专题介绍游戏制作的GB码中文网站,收录个人文章超过百万字, 在游戏界颇有名气。1998年中发布看书工具C-View 2.0,被多张工具光盘收藏。
1999年初开始制作二维游戏引擎--风魂系列,被多家公司和小组用于游戏制作。至今风魂系列仍被津津乐道。曾任网易杭州研究中心总监,是网易《大话西游》、《梦幻西游》等游戏的主要开发者,他在2011年9月从网易辞职,并与前网易COO詹钟晖联合创办了简悦(EJOY)游戏公司,任公司CTO。
再说说国外的一些C++牛人:
Bjarne Stroustrup
Bjarne Stroustrup,不认识的可以去面壁了,没有他,就没有我们现在的饭碗。Bjarne Stroustrup是丹麦人,目前任教于TAMU。他的Homepage和他的书籍The C++ Programming Language一样,都是百科全书级的,如果你认真研究,你也会成为你同事或周围人的C++之父。
Scott Meyers
http://scottmeyers.blogspot.com/
Scott Meyers,不多介绍,世界上几乎每个C++程序员都应该知道的名字,畅销书:Effective C++, More Effective C++的作者。博客长期更新,就凭Scott Meyers这个名字,就值得一读。
Stanley B.Lippman
http://scottmeyers.blogspot.com/
Lippman,C++第一个编译器Cfront的实现者,最大的贡献是凭借其著作C++ Primer在世界范围内普及了C++。Lippman本人算是个励志故事,父母是蓝领移民,他为了融入美国主流社会而努力工作,终于取得了今日的成就,他的另一本书Inside The C++ Object Model让我知道了C++代码编译后的样子,不过我不知他写该书时发生了什么事情,因为书中有大量的低级错误,与前一本书的严谨截然相反。列出他的博客,更多的是因为他是C++牛人中无法绕过的一个,而其博客久不更新,早已荒芜,而且是MSDN上的专栏,可能不太能提起人多大兴趣去读。
Herb Sutter
Herb Sutter, C++标准委员会主席,目前就职于微软。代表作为C++ Exceptional系列:
Exceptional C++, More Exceptional C++, Exceptional C++ Style, 因封面头像蓄须,被国人称“小胡子”,不过貌似现在刮干净了。博客更新很快,内容杂乱,有技术亦有资讯,gotw系列个人感觉不错.
Andrei Alexandrescu
Andrei Alexandrescu,罗马尼亚人,目前任职于FaceBook, C++天书Modern C++ Design: Generic Programming and Design Patterns Applied的作者,凭借此书使C++社区认识到模板编程鬼斧神工之力。后来不满C++而转投D语言,是D语言的主要开发者。不过他的博客貌似好久不更新了,内容也大多学术气息浓厚。
David Abrahams
David Abrahams,美国人,C++标准委员会成员,将exception-safety加入标准,
http://Boost.org的联合创始人,C++ Template Metaprogramming的作者。但博客内容一般,最后一篇内容更新时间是12年的,内容不多,也没有太多亮点,不过笑容却是感染了我。
Bartosz Milewski
Bartosz Milewski's Programming Cafe
Bartosz Milewski,波兰人,物理系毕业的计算机大牛,曾就职于微软。c++ in action的作者。博客更新频繁,内容密实,观点前卫,对C++的不满流露于字里行间,多以Haskell对比C++的不足,然后实现一些函数式编程风格的C++代码。
Anthony Williams
Anthony Williams,英国人,一个记事起就开始写程序的人。Boost.Thread的作者,参与了C++11 Thread的标准化工作。博客有一部分技术文章,也有一些标准化和他自己维护的一些库的记录,对C++多线程感兴趣的可以读一下他的书:C++ Concurrency in Action,市面上第一本讲解C++11并发的权威书籍。
Alexander A. Stepanov
Alexander A. Stepanov,出生于莫斯科,STL之父,编程原本的作者。Alexander A. Stepanov的这个博客如其名,是他个人学术论文的整理,学术价值应该是蛮高吧,不过像我这种低级程序员只能远观了。
Matt Austern
Matt Austern, 现任职于Google, 前C++标准委员会主席,SCG STL的最初实现者,Generic Programming and the STL的作者。Matt Austern的这个博客其实是个人主页,没有太多技术东西,只是一些生平和生活照片,无聊的看一下倒还行。
P.J. Plauger
P.J. Plauger,这个名字可能不是每个人都听说过,但在Windows平台开发的同学肯定都用过他写的代码,他就是MS VC STL库的实现者。本来他的博客,只是个人主页并且上面没什么内容,不过看到他的履历里面完成了13部科幻小说的编写,拿来勉励大家吧。
Andrzej Krzemieński
http://akrzemi1.wordpress.com/
Andrzej Krzemieński,从名字看是波兰人,近期博客更新较快,表达清晰,行文流畅,内容难度不高,有C++11内容,是像我这样的初级并且语言控的C++程序员的福音。
Sumant Tambe
http://cpptruths.blogspot.com/
Sumant Tambe,印度人,美国范德堡大学的计算机博士,技术涉猎广泛,同时也是著名的More C++ Idioms创建者。博客一直更新,内容面向中高级C++程序员,最新文章涉及C++11的“高级Idioms”,比如13年10月的一篇文章主题是:创建递归的lambda表达式。
Jeff Preshing
Jeff Preshing,加拿大人,自称游戏行业开发10数年,C++功力自是深厚。博客每年更新十数篇,C++相关文章内容上进,直面工程上的难题:并发,而不是在C++本身上打转转。且行为流畅,图文并茂,深入浅出,是C++工程控的福音。
Joaquín M López Muñoz
Joaquín M López Muñoz,西班牙人。Boost.MultiIndex的实现者。博客长期更新,内容偏向算法,文章中有大量的公式推演和曲线图表,估计大部分中国开发者对这种内容是不感冒的。计算机或数学系的研究生,并以后打算从事算法相关工作的,推荐阅读。从这个西班牙男人身上,也可以看到老牌欧洲资本主义国家,教育水平的强悍,尤其是基础学科。
Daniel Park
http://functionalcpp.wordpress.com/
Daniel Park,喜欢用昵称whanhee,身世不知。一个注重实干的C++狂热分子,正如其博客简介所说,不想接着讲那些被讲烂掉的函数式编程概念,要用C++来实现这些概念。博客是一个关于函数式编程概念如何用C++实现的一个系列文章,作者采用的是C++11乃至C++14的特性,所以对C++高级函数式实现思想感兴趣的不容错过。近期博客更新也较快的。
Agustín Bergé
http://talesofcpp.fusionfenix.com/
Agustín Bergé,86年生阿根廷人,可能是这里面最年轻的,stackoverflow目前排名708。作者想用自己的博客探索永无边界的C++世界,尤其是那些前人未涉足的犄角旮旯,所以C++中毒颇深者可以看看。
Chris Kohlhoff
Thinking Asynchronously in C++
Chris Kohlhoff,澳大利亚人,Boost.asio作者。博客更新到10年,内容主要涉及网络,asio相关,使用asio的可以去看看。
作者:玩转Github 链接: https://www.zhihu.com/question/457700447/answer/2327524834 来源:知乎
如果感觉学习C++比较吃力,初学者推荐课本+视频的方式学习。这里推荐,B站上面侯捷 C++ 视频课程一直都被看过的同学广为推荐,最近发现 B 站关于侯捷老师的 C++ 视频课程几乎全部被下架了,于是自己搜集了一套非常全的视频,大家赶紧去下载保存备用:
学好C++才是入职大厂的敲门砖! 当年要是有这课,我的C++也不至于这样已失效 .大家只知道程序员工资高,同样的,选择了程序员这条路也要做好付出更多努力的准备,未来的路很长,我们终身学习,共勉。
最后,计算机基础很重要,如果能参考国内一流大学的教材来学,更能是事半功倍,包含了浙大计算机专业 4 年所学内容:教材+课件+试卷+PPT等等::
今年秋招已经开始了,很多同学问我大厂面试的核心知识点,东哥熬夜整理出来了9大核心知识点,需要的自取:
另外,我当初在准备各大公司技术笔试的时候刷了大量的算法题,其中就是参考了一本谷歌大神的LeetCode刷题笔记,帮我整理了解题思路,归纳了出刷题方法,非常不出错,转给需要的同学:
码字不易,硬核码字更难,希望大家不要吝啬自己的鼓励,给我 :
一个点赞,鼓励下我!
我将从两个方面谈谈:一方面会引用我很喜欢的Nathan的一篇关于写博客的文章俩回答这个问题;第二方面是从我自己的切身感受来回答这个问题。
一、Nathan的感悟
我比较喜欢Nathan(Apache Storm的创始人)的一篇博客:《You should blog even if you have no readers》,可以用来回答这个问题,内容如下:
Spencer Fry wrote a great post on "Why entrepreneurs should write." I would further add that the benefits of writing are so extraordinary that you should write a blog even if you have no readers (and regardless of whether you're an entrepreneur).
I have over 50 unfinished drafts. Some of them are just a few ideas scribbled down arguing with myself. Most of them will never be published, yet I got value out of writing all of them.
Writing makes you a better reader
Blogging has changed how I read other people's writing.
In struggling to find the right ways to structure and present my posts, I am much more attuned to what makes a good argument and what makes a bad argument. I am better at seeing holes in other people's reasoning.
At the same time, when reading I am less likely to fall into the trap of discrediting a post with weak counterclaims. In most any post, there are likely to be counterclaims that are based on exceptional cases. Internet commenters love to point these out. However, these exceptional cases miss the main thrust of the post, and by understanding the implicit backdrop behind a post's argument, I get a lot more value out of reading.
I'm also more aware of the style of good writers. I mentally take note of the ways good writers phrase their ideas. I'd always enjoyed Paul Graham's writing, but now I really appreciate how he organizes his posts. He has an awesome ability to suck you into his world and show you what it looks like from his perspective. I've learned a lot about good writing from reading Bradford Cross's blog; his posts have a clear arc and make excellent use of short paragraphs to keep the posts flowing.
Writing makes you smarter
Writing reveals holes in your thinking. When your ideas are written and looking back at you, they're a lot less convincing than when they're just in your head. Writing forces you to mature your ideas by thinking through counterarguments.
Writing helps you organize your thoughts in a coherent way. This makes you a much better conversationalist when these topics come up. I can't count the number of times I've had deeper conversations with people because I had matured my ideas offline.
Consider anything else a side benefit
Everything else writing gives you -- personal branding, networking, inbound opportunities -- are just side benefits. They're potentially very large side benefits, but they are not the main reason you should write.
You should write because writing makes you a better person.
二、我自己的感悟
我大约从2004年开始写技术博客,陆陆续续坚持到了现在,写了也有十几年了。
自己感觉到的好处:
1、锻炼表达能力;2、积累知识点;3、帮助自己快速找回曾经熟悉的内容;4、逼迫自己思考一些问题,将知识从点变成线或者网;5、增强自己在圈子内的影响力。
——————————————————————————————
2024年6月2日修改:给原来的内容加上了两个标题,以方便大家区分两个部分的内容。之前有评论似乎把两个部分搞混了。



