×

mysql千万级查询大约多久

mysql千万级查询大约多久(mysql 千万级数据统计,怎么提高查询速度呀,怎么才能达到5秒内,用了索引也慢,现在非常急)

admin admin 发表于2024-07-11 20:53:57 浏览16 评论0

抢沙发发表评论

“mysql千万级查询大约多久”相关信息最新大全有哪些,这是大家都非常关心的,接下来就一起看看mysql千万级查询大约多久(mysql 千万级数据统计,怎么提高查询速度呀,怎么才能达到5秒内,用了索引也慢,现在非常急)!

本文目录

mysql 千万级数据统计,怎么提高查询速度呀,怎么才能达到5秒内,用了索引也慢,现在非常急

优化下mysql的参数如果是linux下是修改my.cnfinnodb_buffer_pool_sizeinnodb_additional_mem_pool_sizeinnodb_log_buffer_size这些都修改大些,如果前面有#就把#去掉

mysql 500W条记录查询大概多长时间

//首先你的先插入500w条数据,我在mysql中建了一张表,只建了两个字段。程序跑了1个小时发生了//Java.lang.OutOfMemoryError: Java heap space  溢出现象,所以不整了浪费时间,自己算一下,//可能我电脑不好,1000条要执行这么久//程序执行时间:31433public static void main(String args) throws Exception {                           long start=System.currentTimeMillis();                Class.forName("com.mysql.jdbc.Driver");                String url="jdbc:mysql://localhost:3306/test";                String username="root";                String password="root";                Connection conn=DriverManager.getConnection(url,username,password);                               for(int i=0;i《5000000;i++){                  PreparedStatement ps = (PreparedStatement) conn.prepareStatement("INSERT INTO mysqltest (NAME) VALUES (’张三’);");                  int rs = ps.executeUpdate();                }                long end=System.currentTimeMillis();                                System.out.println("程序执行时间:"+(end-start));            }//你自己运行一下。//堆空间溢出,可以去看看这里:

mysql更新10万条数据要多久

mysql更新10万条数据要三个多小时。根据查询相关公开信息,批量更新表中某个字段,如果表比较大,每条记录都执行一条update,1秒执行10条数据,10万条数据就要1W秒,3个多小时。

MySQL删除千万级数据量导致的慢查询优化

有人删了千万级的数据,结果导致频繁的慢查询。

线上收到大量慢查询告警,于是检查慢查询的SQL,发现不是啥复杂SQL,这些SQL主要针对一个表,基本都是单行查询,看起来应该不会有慢查询。这种SQL基本上都是直接根据索引查找出来的,性能应该极高。

是否可能慢查询不是SQL问题,而是MySQL生产服务器的问题?特殊情况下,MySQL出现慢查询还真不是SQL问题,而是他自己生产服务器的负载太高,导致SQL语句执行慢。比如现在MySQL服务器的

磁盘I/O负载高,每秒执行大量高负载的随机I/O,但磁盘本身每秒能执行的随机I/O有限,导致正常SQL在磁盘执行时,若跑一些随机IO,你的磁盘太忙,顾不上你了,导致你本来很快的一个SQL,要等很久才能执行完毕,这时就可能导致正常SQL也变成慢查询。

也许网络负载高,导致你一个SQL语句要发到MySQL,光是等待获取一个和MySQL的连接,都很难,要等很久或MySQL自己网络负载太高,带宽打满,带宽打满后,你一个SQL也许执行很快,但其查出来的数据返回给你,网络都送不出去,也会变成慢查询。

若CPU负载过高,也会导致CPU过于繁忙去执行别的任务,没时间执行你的SQL。

所以慢查询不一定是SQL本身导致,若觉得SQL不应该会慢查询,结果他那个时间段跑这个SQL 就是慢,应排查当时MySQL服务器的负载,尤其看看磁盘、网络及 CPU 的负载,是否正常。

当某个离线作业瞬间大批量把数据往MySQL里灌入的时,他一瞬间服务器磁盘、网络以及CPU的负载会超高。

此时你一个正常SQL执行下去,短时间内一定会慢查询,类似问题,优化手段更多是控制你导致MySQL负载过高的那些行为,比如灌入大量数据,最好在业务低峰期灌入,别影响高峰期的线上系统运行。

但看了下MySQL服务器的磁盘、网络以及CPU负载,一切正常,似乎也不是这问题导致。看起来无解了?

慢 SQL 的头两步排查手段:

这两种办法都不奏效之后,第三步:用MySQL profilling工具去细致的分析SQL语句的执行过程和耗时。

这个工具可以对SQL语句的执行耗时进行非常深入和细致的分析

打开profiling,使用

接着MySQL就会自动记录查询语句的profiling信息。此时若执行show profiles,就会给你列出各种查询语句的profiling信息,会记录下来每个查询语句的query id,所以你要针对你需要分析的query找到对他的query id,我们当时就是针对慢查询的那个SQL语句找到了query id。

然后针对单个查询语句,看其profiling信息,使用show profile cpu, block io for query xx,这里的xx是数字,此时就可以看到具体的profile信息。

除了cpu以及block io以外,还能指定去看这个SQL语句执行时候的其他各项负载和耗时。

会给你展示出来SQL语句执行时候的各种耗时,比如磁盘IO的耗时,CPU等待耗时,发送数据耗时,拷贝数据到临时表的耗时等,SQL执行过程中的各种耗时都会展示。

检查该SQL语句的profiling信息后,发现问题,其Sending Data耗时最高,几乎使用1s,占据SQL执行耗时的99%!其他环节耗时低可以理解,毕竟这种简单SQL执行速度真的很快,基本就是10ms级别,结果跑成1s,那肯定Sending Data就是问题根源!

这Sending Data在干啥呢?

MySQL官方释义:为一个SELECT语句读取和处理数据行,同时发送数据给客户端的过程,简单来说就是为你的SELECT语句把数据读出来,同时发送给客户端。

但这过程为啥这么慢?profiling确实是提供给我们更多的线索了,但似乎还是没法解决问题。但已经捕获到异常关键点,就是Sending Data的耗时很高!

接着:

看innodb存储引擎的一些状态,此时发现一个奇怪的指标:history list length,值特别高,达到上万。

MVCC就是多个事务在对同一个数据, 有人写,有人读,此时可以有多种隔离级别,对一个数据有个多版本快照链条,才能实现MVCC和各种隔离级别。

所以当你有大量事务执行时,就会构建这种undo多版本快照链条,此时history list length就会很高。然后在事务提交后,会有一个多版本快照链条的自动purge清理机制,清理了,该值就会降低。一般该值不应过高,所以注意到第二个线索:history list length过高,即大量的undo多版本链条数据没有清理。推测可能有的事务长时间运行,所以其多版本快照不能被purge清理,进而导致history list length过高。

经过这俩线索推测,在大量简单SQL变成慢查询时,SQL因为Sending Data环节异常,耗时过高;同时此时出现一些长事务长时间运行,大量的频繁更新数据,导致有大量undo多版本快照链条,还无法purge清理。

因为发现有大量的更新语句在活跃,而且有那种长期活跃的长事务一直在跑而没有结束,问了下系统负责人,在后台跑了个定时任务:他居然开了一个事务,然后在一个事务里删除上千万数据,导致该事务一直在运行。

这种长事务的运行会导致你删除时,仅只是对数据加了一个删除标记,事实上并没有彻底删除。此时你若和长事务同时运行的其它事务里再查询,他在查询时可能会把那上千万被标记为删除的数据都扫描一遍。因为每次扫描到一批数据,都发现标记为删除了,接着就会再继续往下扫描,所以才导致一些查询语句很慢。

那为何你启动一个事务,在事务里查询,凭什么就要去扫描之前那个长事务标记为删除状态的上千万的垃圾数据?讲道理,那些数据都被删了,跟你没关系了呀,你可以不去扫描他们 嘛!

而问题症结在于,那个 删除千万级数据的事务是个长事务 !即当你启动新事务查询时,那个删除千万级数据的长事务一直在运行,它是活跃的!结合MVCC的Read View机制,当你启动一个新事务查询时,会生成一个Read View。你的新事务查询时,会根据ReadView去判断哪些数据可见及可见的数据版本号,因为每个数据都有个版本链条,有时你能可见的仅是这个数据的一个 历史 版本。

所以正是因为该长事务一直在运行,还在删除大量数据,而且这些数据仅是逻辑删除,所以此时你新开事务的查询还是会读到所有逻辑删除数据,也就会出现千万级的数据扫描,导致了慢查询!

所以禁止在业务高峰期运行那种删除大量数据的语句,因为这可能导致一些正常的SQL都变慢查询,因为那些SQL也许会不断扫描你标记为删除的大量数据,好不容易扫描到一批数据,结果发现是标记为删除的,于是继续扫描下去,导致慢查询!

直接kill那个正在删除千万级数据的长事务,所有SQL很快恢复正常。此后,大量数据清理全部放在凌晨执行,那个时候就没什么人使用系统了,所以查询也很少。

mysql百万数据分页查询4秒,求教怎么优化

很多应用往往只展示最新或最热门的几条记录,但为了旧记录仍然可访问,所以就需要个分页的导航栏。然而,如何通过MySQL更好的实现分页,始终是比较令人头疼的问题。虽然没有拿来就能用的解决办法,但了解数据库的底层或多或少有助于优化分页查询。我们先从一个常用但性能很差的查询来看一看。SELECT *FROM cityORDER BY id DESCLIMIT 0, 15这个查询耗时0.00sec。So,这个查询有什么问题呢?实际上,这个查询语句和参数都没有问题,因为它用到了下面表的主键,而且只读取15条记录。CREATE TABLE city ( id int(10) unsigned NOT NULL AUTO_INCREMENT, city varchar(128) NOT NULL, PRIMARY KEY (id)) ENGINE=InnoDB;真正的问题在于offset(分页偏移量)很大的时候,像下面这样:SELECT *FROM cityORDER BY id DESCLIMIT 100000, 15;上面的查询在有2M行记录时需要0.22sec,通过EXPLAIN查看SQL的执行计划可以发现该SQL检索了100015行,但最后只需要15行。大的分页偏移量会增加使用的数据,MySQL会将大量最终不会使用的数据加载到内存中。就算我们假设大部分网站的用户只访问前几页数据,但少量的大的分页偏移量的请求也会对整个系统造成危害。Facebook意识到了这一点,但Facebook并没有为了每秒可以处理更多的请求而去优化数据库,而是将重心放在将请求响应时间的方差变小。对于分页请求,还有一个信息也很重要,就是总共的记录数。我们可以通过下面的查询很容易的获取总的记录数。SELECT COUNT(*)FROM city;然而,上面的SQL在采用InnoDB为存储引擎时需要耗费9.28sec。一个不正确的优化是采用 SQL_CALC_FOUND_ROWS,SQL_CALC_FOUND_ROWS 可以在能够在分页查询时事先准备好符合条件的记录数,随后只要执行一句 select FOUND_ROWS(); 就能获得总记录数。但是在大多数情况下,查询语句简短并不意味着性能的提高。不幸的是,这种分页查询方式在许多主流框架中都有用到,下面看看这个语句的查询性能。SELECT SQL_CALC_FOUND_ROWS *FROM cityORDER BY id DESCLIMIT 100000, 15;这个语句耗时20.02sec,是上一个的两倍。事实证明使用 SQL_CALC_FOUND_ROWS 做分页是很糟糕的想法。下面来看看到底如何优化。文章分为两部分,第一部分是如何获取记录的总数目,第二部分是获取真正的记录。高效的计算行数如果采用的引擎是MyISAM,可以直接执行COUNT(*)去获取行数即可。相似的,在堆表中也会将行数存储到表的元信息中。但如果引擎是InnoDB情况就会复杂一些,因为InnoDB不保存表的具体行数。我们可以将行数缓存起来,然后可以通过一个守护进程定期更新或者用户的某些操作导致缓存失效时,执行下面的语句:SELECT COUNT(*)FROM cityUSE INDEX(PRIMARY);获取记录下面进入这篇文章最重要的部分,获取分页要展示的记录。上面已经说过了,大的偏移量会影响性能,所以我们要重写查询语句。为了演示,我们创建一个新的表“news”,按照时事性排序(最新发布的在最前面),实现一个高性能的分页。为了简单,我们就假设最新发布的新闻的Id也是最大的。CREATE TABLE news( id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, title VARCHAR(128) NOT NULL) ENGINE=InnoDB;一个比较高效的方式是基于用户展示的最后一个新闻Id。查询下一页的语句如下,需要传入当前页面展示的最后一个Id。SELECT *FROM news WHERE id 《 $last_idORDER BY id DESCLIMIT $perpage查询上一页的语句类似,只不过需要传入当前页的第一个Id,并且要逆序。SELECT *FROM news WHERE id 》 $last_idORDER BY id ASCLIMIT $perpage上面的查询方式适合实现简易的分页,即不显示具体的页数导航,只显示“上一页”和“下一页”,例如博客中页脚显示“上一页”,“下一页”的按钮。但如果要实现真正的页面导航还是很难的,下面看看另一种方式。SELECT idFROM ( SELECT id, ((@cnt:= @cnt + 1) + $perpage - 1) % $perpage cnt FROM news JOIN (SELECT @cnt:= 0)T WHERE id 《 $last_id ORDER BY id DESC LIMIT $perpage * $buttons)CWHERE cnt = 0;通过上面的语句可以为每一个分页的按钮计算出一个offset对应的id。这种方法还有一个好处。假设,网站上正在发布一片新的文章,那么所有文章的位置都会往后移一位,所以如果用户在发布文章时换页,那么他会看见一篇文章两次。如果固定了每个按钮的offset Id,这个问题就迎刃而解了。Mark Callaghan发表过一篇类似的博客,利用了组合索引和两个位置变量,但是基本思想是一致的。如果表中的记录很少被删除、修改,还可以将记录对应的页码存储到表中,并在该列上创建合适的索引。采用这种方式,当新增一个记录的时候,需要执行下面的查询重新生成对应的页号。SET p:= 0;UPDATE news SET page=CEIL((p:= p + 1) / $perpage) ORDER BY id DESC;当然,也可以新增一个专用于分页的表,可以用个后台程序来维护。UPDATE pagination TJOIN ( SELECT id, CEIL((p:= p + 1) / $perpage) page FROM news ORDER BY id)CON C.id = T.idSET T.page = C.page;现在想获取任意一页的元素就很简单了:SELECT *FROM news AJOIN pagination B ON A.id=B.IDWHERE page=$offset;还有另外一种与上种方法比较相似的方法来做分页,这种方式比较试用于数据集相对小,并且没有可用的索引的情况下—比如处理搜索结果时。在一个普通的服务器上执行下面的查询,当有2M条记录时,要耗费2sec左右。这种方式比较简单,创建一个用来存储所有Id的临时表即可(这也是最耗费性能的地方)。CREATE TEMPORARY TABLE _tmp (KEY SORT(random))SELECT id, FLOOR(RAND() * 0x8000000) randomFROM city; ALTER TABLE _tmp ADD OFFSET INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, DROP INDEX SORT,ORDER BY random;接下来就可以向下面一样执行分页查询了。SELECT *FROM _tmpWHERE OFFSET 》= $offsetORDER BY OFFSETLIMIT $perpage;简单来说,对于分页的优化就是。。。避免数据量大时扫描过多的记录。

mysql查询上万条数据要多久

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件。

mysql查一个百万的数据表要多久

看这个表的设计怎样,还有你访问的语句怎样。如果表设计的比较好,关键字段建立了索引,而且你查询语句也用到了索引并起作用,那么查一百多万的数据也是10秒以内的事。

mysql查询六千万条数据不到1s正常吗

不怎么正常 通常mysql的性能 是没有 oracle的 好的。除了 你的sql 优化的特别好 。也是要超过一秒的。这么多数据 IO的

2016 mysql 几千万级大表 多表查询 大概多久

很多人第一反应是各种切分;我给的顺序是:第一优化你的sql和索引;第二加缓存,memcached,redis;第三以上都做了后,还是慢,就做主从复制或主主复制,读写分离,可以在应用层做,效率高,也可以用三方工具,第三方工具推荐360的atlas,其它的要么效率不高,要么没人维护;第四如果以上都做了还是慢,不要想着去做切分,mysql自带分区表,先试试这个,对你的应用是透明的,无需更改代码,但是sql语句是需要针对分区表做优化的,sql条件中要带上分区条件的列,从而使查询定位到少量的分区上,否则就会扫描全部分区,另外分区表还有一些坑,在这里就不多说了;第五如果以上都做了,那就先做垂直拆分,其实就是根据你模块的耦合度,将一个大的系统分为多个小的系统,也就是分布式系统;第六才是水平切分,针对数据量大的表,这一步最麻烦,最能考验技术水平,要选择一个合理的sharding key,为了有好的查询效率,表结构也要改动,做一定的冗余,应用也要改,sql中尽量带sharding key,将数据定位到限定的表上去查,而不是扫描全部的表;

如何设计一个能够高效查询的千万级MySQL数据库

首先要确定你的目标,所谓千万级是每秒千万次查询还是千万条记录的数据库,前者是一个极其复杂的,这个不是光告mysql能解决的,我想不是前者,而后者却是很简单的一件事,前提是定义高效,定义两个指标:

1,每秒查询的次数是多少

2,每次查询时长

确定好以后再考虑以下几个因素的优化

1,存储的类型,SSD比普通磁盘的随机读写能力可以提高不少,一般2到3个数量级,还要看索引和数据块的大小,比较复杂

2,先择RAID类型,如果选raid0和raid10可以提升近似1倍的速度

3,使用高带宽的网速,可以减少网络传输延迟,用10g的光纤比1g的电缆理论上可以提升1个数量级的吞吐量,尤其对大数据据量的结果集特别有效

4,合理的索引,带条件的检索字段加上索引

5,用大宽表,尽可能减少多表关联查询,用空间换时间吧

6,_用主从的集群,基本上查询的并发量和服务器的数量成正比的

7,使用缓存,如memcached,尤其对静态数据提升尤其明显

8,合理选择数据库字段的类型,用定长字字,不要用变长的,如定长的int,char,decimal类型,别用varchar,text等

9,给数据库配置更大的内存

10,检查下瓶颈在不在CPU,如果查询复杂,换个更高配置的服务器

总的原刚就是,尽可能用内存替代碰盘提升IO速度,提高网络和CPU的配置以减少查询时间;尽可能提升网络速度,内存和主机的数量以提高并发


我们先探讨非高并发量的实现。

对于查询频次较高的字段,加上索引。

加索引注意事项:

1.对那些字符内容较长的最好不要加索引

2.按照官方文档,单表加的索引不要超过16个,索引的长度不要超过256个字节。

随意加索引,会给数据维护增加负担

其实,可以引入分区。

分区注意事项:

1.常见的分区类型有range,list,hash,key等。用的比较多的就是range分区。

2.对于初始建立索引的时候,我们往往会忽视一个前提条件,导致添加失败报错。

这里的前提是,如果表是有主键的,分区的键和主键不是同一个,那么分区的键也必须是主键。

引入分区后,数据写入时,数据库会自动判断写入哪个分区

对于并发量较高的,我们除了做上面的操作外,就要考虑分库分表或者采用一主多从的方式。

未来我相信这类问题需要采用NewSQl这类数据库来解决,如TiDb等,此时,我们将不必考虑数据分区的问题,而且可以做到数据水平无限扩展,和热点数据的动态分布。


关于mysql千万级查询大约多久和mysql 千万级数据统计,怎么提高查询速度呀,怎么才能达到5秒内,用了索引也慢,现在非常急的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。