MySQL当表数据量极大时[单张表800万条记录],如何提高查询及更新速度?

时间:2021-03-04 23:20:41
我要处理一个有800万条记录的大表数据。

数据处理算法如下:

1.在内存中创建一个空的临时表: temp 

2.将这有800万条记录的表(Recordset=SOURCE)按带索引的主键排序后,然后通过循环语句用游标从第一条记录访问到最后一条记录。

3.在对“SOURCE”遍历过程中,每读到一条记录,进行如下操作:
   
   如果SOURCE记录中的“字段A”=1 则将其写入到临时表temp
   
   否则“字段A”<>1 通过SQL语句在临时表temp中查询与此SOURCE记录相关的temp记录,如果在temp中找到了相关记录,则从temp中取出相关的字段值,更新SOURCE当前记录的相关字段.然后将temp中的这条记录删除。
  
 ( 注SOURCE中的每条记录“字段A”并不是全部等于1的,它是随机出现的。 )


    
我想问的问题是:针对当前的数据分析算法如何提高处理速度 (具体的要点如下)? 【目前的处理速度相当慢!】

一、数据库表“SOURCE ”的存储引擎是用MyISAM还是用InnoDB 好?

二、对于大表【例如:超过800万条记录的表】的查询、更新操作,是否可以从数据处理算法上提高数据处理速度?比如将大表人为分割成多个小表,然后对通程序的多线程技术来“并发”处理多个表?如果您有这方面的工程经验,能否给我一点思路?

三、大表的索引及主键创建原则及各类查询的SQL语句设计原则是什么?我目前想到的是WHERE及ORDER BY之后的字段要创建 索引。SQL的分析树、执行计划与SQL语句和表的关系如何?

这个问题比较复杂,要提高数据库的数据处理速度确实是一个难题!

多谢!








10 个解决方案

#1


第18章:分区
目录
18.1. MySQL中的分区概述
18.2. 分区类型
18.2.1. RANGE分区
18.2.2. LIST分区
18.2.3. HASH分区
18.2.4. KEY分区
18.2.5. 子分区
18.2.6. MySQL分区处理NULL值的方式
18.3. 分区管理
18.3.1. RANGE和LIST分区的管理
18.3.2. HASH和KEY分区的管理
18.3.3. 分区维护
18.3.4. 获取关于分区的信息

#2


1, 这个情况适用于myisam
2, 有必要用游标吗? 两条语句就搞定的事
insert into temp (...) select ..... from source where 字段1=1
update source inner join temp on 关联条件 set ... 
3, 多去熟悉些基础知识先

#3


 为了将问题描述的简单一点,突出我想问的问题重点——即对大表的操作算法,我已经将我处理数据算法精简了很多了。

我可以确认用简单的SQL是不可能实现数据分析的。实际上,"字段A"=1,这个条件并不是一成不变的,随着消息量的逐渐增加,条件可能会发生随机变化:,"字段A"=15,。。。,"字段A"=18 。。。实际上我在分析SOURCE中各条记录之间的相关性。其相关性是通过SOURCE中的某几个字段产生联系的,而这几个字段的内容又是随记录的不断增加内容也是在不断随机变化(还有可能和之前的值相同),总之,际实处理上绝对不可能用简单的SQL查询实现分析SOURCE中各记录之间的相关性。



#4


到如今暂未碰到过所谓的必须用游标循环而我不能用关系查询解决的。 
只能说从性能和条件限制,是否适用于关系查询来实现。

#5


按楼主的说法是一定要对表进行全表扫描,这种情况下没什么优化之说了。 速度只取决于你的硬件IO速度。

#6


如何分析数据处理慢是慢在哪里?有没有类似于DEGBUG的分析工具?

我现在的想法是从程序的架构上看:800万条记录(source table)处理,对于每一条记录均需要去内存临时表temp中SELECT一下或UPDATE一下,然后更新source table,是处理流程的问题。如楼上高手所说用SQL去UPDATE会很快,这个说法我认同。

还有一个问题是,即使所有操作均用SQL完成,但我们也会遇到处理“大表”的问题。在处理大表时分区操作是否很有效呢,即可以大幅提高数据处理速度?

首先,我本人不是专业从事软件开发的,没有开发经验,多谢各位了!

分区的问题我一会仔细研究一下。

#7


我觉的这个应该首先考虑下访问量和硬件的因素,否则访问量非常大并且都是动态页面。800万条数据够服务器喝一壶的。推荐看一下这个文章:http://andrewyu.blog.51cto.com/1604432/509635。
其次,如果访问量大,提高硬件IO速度,分表应该是可行的方法。
最后,优化查询语句,建索引,用存储过程降低通信量。

总觉得本机200万数据建立索引后查询还是非常快的,不过LS各位大牛的意见更好。

#8


技术上解决不了的那就从业务上解决

#9


数据库里的游标运行速度慢是没办法解决的。

#10



多谢各位.我再想想办法吧.

思路:

从应用分析算法上优化、SQL语句优化、原始表结构优化.

#1


第18章:分区
目录
18.1. MySQL中的分区概述
18.2. 分区类型
18.2.1. RANGE分区
18.2.2. LIST分区
18.2.3. HASH分区
18.2.4. KEY分区
18.2.5. 子分区
18.2.6. MySQL分区处理NULL值的方式
18.3. 分区管理
18.3.1. RANGE和LIST分区的管理
18.3.2. HASH和KEY分区的管理
18.3.3. 分区维护
18.3.4. 获取关于分区的信息

#2


1, 这个情况适用于myisam
2, 有必要用游标吗? 两条语句就搞定的事
insert into temp (...) select ..... from source where 字段1=1
update source inner join temp on 关联条件 set ... 
3, 多去熟悉些基础知识先

#3


 为了将问题描述的简单一点,突出我想问的问题重点——即对大表的操作算法,我已经将我处理数据算法精简了很多了。

我可以确认用简单的SQL是不可能实现数据分析的。实际上,"字段A"=1,这个条件并不是一成不变的,随着消息量的逐渐增加,条件可能会发生随机变化:,"字段A"=15,。。。,"字段A"=18 。。。实际上我在分析SOURCE中各条记录之间的相关性。其相关性是通过SOURCE中的某几个字段产生联系的,而这几个字段的内容又是随记录的不断增加内容也是在不断随机变化(还有可能和之前的值相同),总之,际实处理上绝对不可能用简单的SQL查询实现分析SOURCE中各记录之间的相关性。



#4


到如今暂未碰到过所谓的必须用游标循环而我不能用关系查询解决的。 
只能说从性能和条件限制,是否适用于关系查询来实现。

#5


按楼主的说法是一定要对表进行全表扫描,这种情况下没什么优化之说了。 速度只取决于你的硬件IO速度。

#6


如何分析数据处理慢是慢在哪里?有没有类似于DEGBUG的分析工具?

我现在的想法是从程序的架构上看:800万条记录(source table)处理,对于每一条记录均需要去内存临时表temp中SELECT一下或UPDATE一下,然后更新source table,是处理流程的问题。如楼上高手所说用SQL去UPDATE会很快,这个说法我认同。

还有一个问题是,即使所有操作均用SQL完成,但我们也会遇到处理“大表”的问题。在处理大表时分区操作是否很有效呢,即可以大幅提高数据处理速度?

首先,我本人不是专业从事软件开发的,没有开发经验,多谢各位了!

分区的问题我一会仔细研究一下。

#7


我觉的这个应该首先考虑下访问量和硬件的因素,否则访问量非常大并且都是动态页面。800万条数据够服务器喝一壶的。推荐看一下这个文章:http://andrewyu.blog.51cto.com/1604432/509635。
其次,如果访问量大,提高硬件IO速度,分表应该是可行的方法。
最后,优化查询语句,建索引,用存储过程降低通信量。

总觉得本机200万数据建立索引后查询还是非常快的,不过LS各位大牛的意见更好。

#8


技术上解决不了的那就从业务上解决

#9


数据库里的游标运行速度慢是没办法解决的。

#10



多谢各位.我再想想办法吧.

思路:

从应用分析算法上优化、SQL语句优化、原始表结构优化.