`
dannyhz
  • 浏览: 397484 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

处理数据库百万级数据的注意点

 
阅读更多
引用

   最近的项目需要用到实现节点的管理规模达到百万规模,需要用数据库对中间数据以及最后的结果进行存储,存储规模可以达到千万级别。初步实现了10万节点数据的存储,但是访问速度实在太慢,查阅相关的资料,发现导致节点插入时间非常慢的原因:
      1、连接数据库的问题:建立连接和关闭连接的次数太多,导致IO访问次数太频繁。
       2、应该使用批量插入和批量修改的方法,而不是有一条数据就进行插入,这样会导致访问数据库的实际特别的慢。
       3、在建立库的时候要建立适当的索引:如主键、外键、唯一等,优化查询效率。
       具体的讨论见此处的链接:http://www.oschina.net/question/1859_62586?sort=default&p=3#answers
       该链接中的一些讨论可以提供思路~
       另外转载的内容如下:
最近一段时间参与的项目要操作百万级数据量的数据,普通SQL查询效率呈直线下降,而且如果where中的查询条件较多时,其查询速度简直无法容忍。之前数据量小的时候,查询语句的好坏不会对执行时间有什么明显的影响,所以忽略了许多细节性的问题。
    经测试对一个包含400多万条记录的表执行一条件查询,其查询时间竟然高达40几秒,相信这么高的查询延时,任何用户都会抓狂。因此如何提高sql语句查询效率,显得十分重要。以下是结合网上流传比较广泛的几个查询语句优化方法:
    首先,数据量大的时候,应尽量避免全表扫描,应考虑在 where 及 order by 涉及的列上建立索引,建索引可以大大加快数据的检索速度。 但是,有些情况索引是不会起效的:
1、应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。
2、应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:
     select id from t where num is null
     可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:
     select id from t where num=0
3、尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:
     select id from t where num=10 or num=20
     可以这样查询:
     select id from t where num=10
     union all
     select id from t where num=20
4、下面的查询也将导致全表扫描:
    select id from t where name like ‘%abc%’
    若要提高效率,可以考虑全文检索。
5、in 和 not in 也要慎用,否则会导致全表扫描,如:
     select id from t where num in(1,2,3)
     对于连续的数值,能用 between 就不要用 in 了:
     select id from t where num between 1 and 3
6、如果在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描:
     select id from t where num=@num
     可以改为强制查询使用索引:
     select id from t with(index(索引名)) where num=@num
7、应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:
     select id from t where num/2=100
     应改为:
     select id from t where num=100*2
8、应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:
     select id from t where substring(name,1,3)=’abc’–name以abc开头的id
     select id from t where datediff(day,createdate,’2005-11-30′)=0–’2005-11-30′生成的id
     应改为:
     select id from t where name like ‘abc%’
     select id from t where createdate>=’2005-11-30′ and createdate<’2005-12-1′
9、不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。
10、在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。
11、不要写一些没有意义的查询,如需要生成一个空表结构:
     select col1,col2 into #t from t where 1=0
     这类代码不会返回任何结果集,但是会消耗系统资源的,应改成这样:
     create table #t(…)
12、很多时候用 exists 代替 in 是一个好的选择:
     select num from a where num in(select num from b)
     用下面的语句替换:
     select num from a where exists(select 1 from b where num=a.num)

    建索引需要注意的地方:
1、并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段 sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。
2、索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。
3、应尽可能的避免更新 clustered 索引数据列,因为 clustered 索引数据列的顺序就是表记录的物理存储顺序,一旦该列值改变将导致整个表记录的顺序的调整,会耗费相当大的资源。若应用系统需要频繁更新 clustered 索引数据列,那么需要考虑是否应将该索引建为 clustered 索引。

    其他需要注意的地方:
1、尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。
2、任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。
3、尽量使用表变量来代替临时表。如果表变量包含大量数据,请注意索引非常有限(只有主键索引)。
4、避免频繁创建和删除临时表,以减少系统表资源的消耗。
5、临时表并不是不可使用,适当地使用它们可以使某些例程更有效,例如,当需要重复引用大型表或常用表中的某个数据集时。但是,对于一次性事件,最好使用导出表。
6、在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果数据量不大,为了缓和系统表的资源,应先create table,然后insert。
7、如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。
8、尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写。
9、使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方案来解决问题,基于集的方法通常更有效。
10、与临时表一样,游标并不是不可使用。对小型数据集使用 FAST_FORWARD 游标通常要优于其他逐行处理方法,尤其是在必须引用几个表才能获得所需的数据时。在结果集中包括“合计”的例程通常要比使用游标执行的速度快。如果开发时间允许,基于游标的方法和基于集的方法都可以尝试一下,看哪一种方法的效果更好。
11、在所有的存储过程和触发器的开始处设置 SET NOCOUNT ON ,在结束时设置 SET NOCOUNT OFF 。无需在执行存储过程和触发器的每个语句后向客户端发送 DONE_IN_PROC 消息。
12、尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。
13、尽量避免大事务操作,提高系统并发能力。

分享到:
评论

相关推荐

    百万级数据在Excel和Sql数据库之间相互导入、导出

    在IT行业中,处理大量...总的来说,正确地在Excel和SQL Server之间导入导出百万级数据需要理解两者的特点,选择合适的方法,并注意数据处理的最佳实践。在实际操作中,应根据具体需求和资源限制来选择最适合的方案。

    java多线程处理数据库数据

    在处理数据库数据时,我们通常会使用JDBC(Java Database Connectivity)API。通过`Connection`对象,我们可以执行SQL语句,如`Statement`或`PreparedStatement`用于增、删、改、查操作。但是,直接在一个线程中频繁...

    阿里的EasyExcel+Mysql方式实现数据库数据导出生成exce

    然后,你可以创建一个处理类,定义一个方法来读取数据库数据并转换为Excel所需的格式。这里通常会涉及到JDBC或者MyBatis等数据库访问技术,用于执行SQL查询获取数据。获取到数据后,使用EasyExcel的write方法将数据...

    java多个数据库实现数据同步

    综上所述,Java实现多数据库数据同步是一个涉及多种技术和策略的复杂问题,需要根据具体业务需求和系统架构来选择合适的方法。在实践中,应注重设计的灵活性、可扩展性和容错性,以保证系统的稳定运行。

    sqlite数据库 大数据量处理demo

    SQLite是一款轻量级的、开源的、自包含的SQL数据库引擎,它被广泛应用于移动设备、嵌入式系统以及各种应用程序中,以处理和存储数据。在这个“sqlite数据库大数据量处理demo”中,我们将深入探讨如何在SQLite数据库...

    8e数据 16e数据库 数据在线查询

    然而,值得注意的是,这种高压缩比可能会导致解压后需要较大的内存资源来处理,尤其是当数据量巨大时。 “内存不足打不开,请换其他工具打开!任何txt工具都可以尝试打开。”这部分提示了打开大型文本文件可能面临...

    DataTable 快速导入数据库——百万条数据只需几秒

    ### DataTable 快速导入数据库——百万条数据只需几秒 在大数据处理的场景下,高效地将大量数据导入数据库是至关重要的。本文将详细介绍如何利用`DataTable`与`SqlBulkCopy`类实现快速的数据批量导入,使百万条数据...

    c#编写的数据库数据转移实例

    在"差异版本,不兼容版本数据库数据转移"的场景下,开发者可能需要考虑以下几点: 1. **数据库架构对比**:使用数据库设计工具或编写脚本来比较源和目标数据库的架构,找出结构差异,如表、字段、索引等的不同。 2...

    labview 数据库的表格创建,数据更新,数据删除,数据查询,数据插入,数据显示。

    总之,LabVIEW结合其数据库工具,为用户提供了强大且灵活的方式来管理和操作数据库,无论是简单的数据操作还是复杂的数据处理任务,都能胜任。通过学习和实践,你可以构建出高效且直观的数据库应用程序。

    数据库表转储到Exl,Exl数据转储到数据库

    为了确保数据导入的准确性和完整性,需要注意以下几点: 1. 数据类型匹配:确保Excel中的数据类型与数据库字段类型一致。 2. 错误处理:处理可能出现的空值、非法数据等问题。 3. 批量插入:为提高效率,可采用批量...

    vc++向数据库中添加数据

    6. 安全性:在向数据库添加数据时,需要注意SQL注入攻击。避免在SQL语句中直接拼接用户输入,而应使用参数化查询或存储过程来提高安全性。 7. 批量插入:如果需要插入大量数据,可以考虑批量操作,以提高效率。这...

    C#、.Net平台大批量提交数据到数据库

    在.NET平台上,C#语言是开发企业级应用的常用工具,尤其在处理大量数据与数据库交互时,其性能和效率显得尤为重要。本话题主要聚焦于如何在C#中实现大批量数据的高效提交到数据库,同时考虑并发处理和不同提交策略。...

    将数据库中的数据转换成sql语句

    在IT行业中,数据库是存储和管理数据的核心工具。在各种业务场景下,有时我们需要将一个数据库中的数据迁移到另一个数据库,这可能涉及到不同版本或不同类型的数据库系统,如MySQL到Oracle,或者SQL Server到...

    JAVA将一个数据中数据定时自动复制(抽取)到另一个数据库

    Java是一种广泛使用的面向对象的编程语言,具有丰富的库和框架,可以方便地处理数据库操作和定时任务。在这个项目中,我们将重点关注两个关键部分:Java线程控制和定时任务。 1. **Java线程控制**:线程是Java中的...

    Excel导入数据库and数据库数据导入Excel

    在IT领域,Excel和数据库之间的数据交互是常见的需求,特别是...无论是Excel导入数据库还是数据库数据导出到Excel,都需要对数据格式、数据转换、异常处理和性能优化有深入的理解,以确保数据的准确性和系统的稳定性。

    java_Excel上传数据到Oracle数据库

    在Java编程环境中,将Excel数据上传到Oracle数据库是一项常见的任务,尤其在数据处理和系统集成中。本项目涉及的关键技术包括Java、jxl库(用于处理Excel文件)和Oracle数据库的连接与操作。以下是对这些知识点的...

    EF基本增删改查附百万级数据测试

    **标题解析:** "EF基本增删改查附百万级数据测试" 指的是使用Entity Framework(简称EF)这个ORM框架进行数据库操作的基本CRUD(Create、Read、Update、Delete)功能,并且包含了对百万级大数据量的性能测试。...

    C#将数据导入excel和Excel数据导入数据库

    此外,注意数据类型匹配,Excel中的数据可能需要转换为适合数据库字段的数据类型。 总之,C#结合NPOI或其他库,配合SQL Server,提供了强大的数据处理能力,可以从Excel文件中提取数据并将其存储到数据库中,这对...

    java连接数据库包、数据报表包

    在Java编程中,连接数据库和生成数据报表是两个核心任务,尤其在企业级应用开发中至关重要。本压缩包包含的资源旨在提供必要的库文件,帮助开发者实现这些功能。以下是相关知识点的详细介绍: 1. **Java数据库连接...

    C#异步操作 异步查询数据库 异步处理一行一行加载数据

    此外,为了确保资源的有效管理,通常会在`using`语句块中处理数据库连接和命令,因为它们实现了`IDisposable`接口。这样,当不再需要时,会自动关闭连接和释放资源。 异步操作的一个重要方面是错误处理。使用`try-...

Global site tag (gtag.js) - Google Analytics