澳门娱乐城   免费注册 查看新帖 |

澳门娱乐城

  平台 澳门娱乐城 博客 文库
最近访问板块 发新帖
查看: 258 | 回复: 0
打印 上一主题 下一主题

Postgresqlwwwhj339com18183609988快速写入/读取大量数据 [复制链接]

全面从严治党,必须坚持和加强党的全面领导。  去年9月,德国举行联邦议院选举。澳门娱乐城,说到老北京城,就不得不说那些曾经各具特色的城门。换言之,每个人都应当在有尊严的前提下,去满足基本的生活需求,坚决反对通过乞讨、卖淫或苦役等方式来满足基本生活需要,防止人们为了外在的物质需求而降低人的高贵和尊严。沙漠边上,这风沙也让人头疼,一年有一半都在刮风,眼睛都睁不开。  政之所行,在顺民心。

九鼎娱乐平台

美方还酝酿在经贸领域发起更多、更严厉的对华贸易施压措施。中俄联合表态:”坚持人与自然和谐共生,从生态文明建设的角度生动诠释了以人民为中心的发展思想。每次巡边,艾山·托合托逊都要越过2条季节河流,翻越12个山岭。“门罗主义”早就是美国干涉、扩张和称霸的一个代名词,并深深嵌进拉美人的血泪史。

赤潮年均爆发次数近60次,浒苔绿潮灾害持续大规模爆发,渤海滨海平原地区海水入侵和土壤盐渍化加重,局部砂质海岸地区海岸侵蚀加重。  在塔克拉玛干沙漠和古尔班通古特沙漠两大沙漠边缘以及数千公里国境沿线,驻守着200多万兵团儿女。九鼎娱乐平台三、揭露所谓“南海仲裁案”临时仲裁庭纯属“草台班子”2013年1月22日,菲律宾单方面将就南中国海问题提交国际仲裁。”  立足于得天独厚的自然生态优势,经过多年精心培育,37万亩生态茶园已经成为印江群众增收致富的“绿色银行”。

记者问:你之前说美方一直在中国南海区域进行抵近侦察活动。曾在中国生活工作过的外国朋友纷纷留言分享亲身经历,表示相比较生活过的其他国家,在中国的经历更安全、更放心。第三师图木舒克市草湖镇的熊英每次到内地沿海城市出差,都会有人向她咨询有关兵团的事情,而每次被问到41团(草湖镇的前身)在地图上什么地方时,熊英都无言以对。首先,坚持市场规律与行政调控相结合,打造一批具有公信力、影响力的舆论平台,展现网络文化的正能量与新时代的精神风貌。

你可以设想一下,如果你在大街上发现了或者捡到了一个东西,而且有人来问你要,你得首先核查验证一下这个东西是否真的是属于那个人,然后才可以给他吧。中俄联合表态:  考核过于刻板僵硬的问题也不容忽视。320个中央和国家机关等单位、21992家民营企业和贫困村一一结对,定点帮扶。测绘队伍将对阿拉尔市建成区开展1500数字地形图测绘(更新)工作,范围为阿拉尔市中心城区西侧10平方公里,工期2个月。

那些别有用心者如果坚持对此保持焦虑并行抹黑之举,等待他们的就只有失信和幻灭的深渊。地窝子和水井是同时诞生的。  “这5户,是当年响应上级政策才搬迁来的移民。兵团民兵担负着全疆15个地州市及兵团辖区重点目标的巡逻警戒任务,是增进民族团结、维护边防安全和社会稳定的重要力量。

而坚定的道路自信、理论自信、制度自信。热门话题之二:全面深改进入攻坚期当前,全面深改已经进入攻坚期和深水区,从政府职能的转变,到城乡发展一体化体制机制的健全,从“农业供给侧改革”到“国企改革”等,都是讨论热词。  除了“独家版权”,天天出版社的曹文轩儿童艺术中心以及中国大百科全书出版社新近成立的雪漠图书中心都引起了出版界的注意。这显示出中国航空工业加快开拓国际市场的雄心壮志,受到国际社会的高度关注。

白手起家

澳门娱乐城徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2019-03-19 11:42 |只看该作者 |倒序浏览
环境及测试
使用.net驱动npgsql连接post数据库。配置:win10 x64, i5-4590, 16G DDR3, SSD 850EVO.
postgresql 9.6.3,数据库与数据都安装在SSD上,默认配置,无扩展。
CREATE TABLE public.mesh(  x integer NOT NULL,  y integer NOT NULL,  z integer,  CONSTRAINT prim PRIMARY KEY (x, y))1. 导入
使用数据备份,csv格式导入,文件位于机械硬盘上,480MB,数据量2500w+。
  • 使用COPYcopy mesh from 'd:/user.csv' csv
    运行时间107s
  • 使用insert
    单连接,c# release any cpu 非调试模式。

class Program{    static void Main(string[] args)    {        var list = GetData("D:\\user.csv");        TimeCalc.LogStartTime();        using (var sm = new SqlManipulation(@"Strings", SqlType.PostgresQL))        {            sm.Init();            foreach (var n in list)            {                sm.ExcuteNonQuery($"insert into mesh(x,y,z) values({n.x},{n.y},{n.z})");            }        }        TimeCalc.ShowTotalDuration();        Console.ReadKey();    }    static List<(int x, int y, int z)> GetData(string filepath)    {        List<ValueTuple<int, int, int>> list = new List<(int, int, int)>();        foreach (var n in File.ReadLines(filepath))        {            string[] x = n.Split(',');            list.Add((Convert.ToInt32(x[0]), Convert.ToInt32(x[1]), Convert.ToInt32(x[2])));        }        return list;    }}
Postgresql CPU占用率很低,但是跑了一年,程序依然不能结束,没有耐性了...,这么插入不行。
  • multiline insert
使用multiline插入,一条语句插入约100条数据。
var bag = GetData("D:\\user.csv");//使用时,直接执行stringbuilder的tostring方法。List<StringBuilder> listbuilder = new List<StringBuilder>();StringBuilder sb = new StringBuilder();for (int i = 0; i < bag.Count; i++){    if (i % 100 == 0)    {        sb = new StringBuilder();        listbuilder.Add(sb);        sb.Append("insert into mesh(x,y,z) values");        sb.Append($"({bag.x}, {bag.y}, {bag.z})");    }    else        sb.Append($",({bag.x}, {bag.y}, {bag.z})");}
Postgresql CPU占用率差不多27%,磁盘写入大约45MB/S,感觉就是在干活,最后时间217.36s。
改为1000一行的话,CPU占用率提高,但是磁盘写入平均来看有所降低,最后时间160.58s.
  • prepare语法
prepare语法可以让postgresql提前规划sql,优化性能。
使用单行插入 CPU占用率不到25%,磁盘写入63MB/S左右,但是,使用单行插入的方式,效率没有改观,时间太长还是等不来结果。
使用多行插入 CPU占用率30%,磁盘写入50MB/S,最后结果163.02,最后的时候出了个异常,就是最后一组数据长度不满足条件,无伤大雅。
static void Main(string[] args){   
var bag = GetData("D:\\user.csv");    List<StringBuilder> listbuilder = new List<StringBuilder>();    StringBuilder sb = new StringBuilder();  
   for (int i = 0; i < bag.Count; i++)    {        if (i % 1000 == 0)        {            sb = new StringBuilder();            listbuilder.Add(sb);         
     //sb.Append("insert into mesh(x,y,z) values");            sb.Append($"{bag.x}, {bag.y}, {bag.z}");        }        else            sb.Append($",{bag.x}, {bag.y}, {bag.z}");    }    StringBuilder sbp = new StringBuilder();    sbp.Append("PREPARE insertplan (");  
       for (int i = 0; i < 1000; i++)    {        sbp.Append("int,int,int,");    }    sbp.Remove(sbp.Length - 1, 1);    sbp.Append(") AS INSERT INTO mesh(x, y, z) values");  
         for (int i = 0; i < 1000; i++)    {        sbp.Append($"(${i*3 + 1},${i* 3 + 2},${i*3+ 3}),");    }    sbp.Remove(sbp.Length - 1, 1);    TimeCalc.LogStartTime();   
          using (var sm = new SqlManipulation(@"string", SqlType.PostgresQL))    {        sm.Init();        sm.ExcuteNonQuery(sbp.ToString());     
             foreach (var n in listbuilder)        {            sm.ExcuteNonQuery($"EXECUTE insertplan({n.ToString()})");        }    }    TimeCalc.ShowTotalDuration();    Console.ReadKey();}
  • 使用Transaction
    在前面的基础上,使用事务改造。每条语句插入1000条数据,每1000条作为一个事务,CPU 30%,磁盘34MB/S,耗时170.16s。
    改成100条一个事务,耗时167.78s。
  • 使用多线程
    还在前面的基础上,使用多线程,每个线程建立一个连接,一个连接处理100条sql语句,每条sql语句插入1000条数据,以此种方式进行导入。注意,连接字符串可以将maxpoolsize设置大一些,我机器上实测,不设置会报连接超时错误。

CPU占用率上到80%, 磁盘这里需要注意,由于生成了非常多个Postgresql server进程,不好统计,累积算上应该有小100MB/S,最终时间,98.18s。
使用TPL,由于Parallel.ForEach返回的结果没有检查,可能导致时间不是很准确(偏小)。
var lists = new List<List<string>>();
var listt = new List<string>();
for (int i = 0; i < listbuilder.Count; i++){  
  if (i % 1000 == 0)    {        listt = new List<string>();        lists.Add(listt);    }    listt.Add(listbuilder.ToString());}TimeCalc.LogStartTime();Parallel.ForEach(lists, (x) =>{  
    using (var sm = new SqlManipulation(@";string;MaxPoolSize=1000;", SqlType.PostgresQL))    {        sm.Init();        foreach (var n in x)        {            sm.ExcuteNonQuery(n);        }    }});TimeCalc.ShowTotalDuration();写入方式耗时(1000条/行)

COPY107s

insertN/A

多行insert160.58s

prepare多行insert163.02s

事务多行insert170.16s

多连接多行insert98.18s
2. 写入更新
数据实时更新,数量可能继续增长,使用简单的insert或者update是不行的,操作使用postgresql 9.5以后支持的新语法。
insert into mesh on conflict (x,y)
do update set z = excluded.z
吐槽postgresql这么晚才支持on conflict,mysql早有了...
在表中既有数据2500w+的前提下,重复往数据库里面写这些数据。这里只做多行插入更新测试,其他的结果应该差不多。
普通多行插入,耗时272.15s。
多线程插入的情况,耗时362.26s,CPU占用率一度到了100%。猜测多连接的情况下,更新互锁导致性能下降。
3. 读取
  • Select方法
标准读取还是用select方法,ADO.NET直接读取。
使用adapter方式,耗时135.39s;使用dbreader方式,耗时71.62s。
  • Copy方法
postgresql的copy方法提供stdout binary方式,可以指定一条查询进行输出,耗时53.20s。
public List<(int x, int y, int z)> BulkIQueryNpg(){    List<(int, int, int)> dict = new List<(int, int, int)>();  
  using (var reader = ((NpgsqlConnection)_conn).BeginBinaryExport("COPY (select x,y,z from mesh) TO STDOUT (FORMAT BINARY)"))    {      
   while (reader.StartRow() != -1)        {           
    var x = reader.Read<int>(NpgsqlDbType.Integer);      
          var y = reader.Read<int>(NpgsqlDbType.Integer);      
        var z = reader.Read<int>(NpgsqlDbType.Integer);            dict.Add((x, y, z));        }    }    return dict;}结论
总结测试结果,对于较多数据的情况下,可以得出以下结论:
  • 向空数据表导入或者没有重复数据表的导入,优先使用COPY语句(为什么有这个前提详见P.S.);
  • 使用一条语句插入多条数据的方式能够大幅度改善插入性能,可以实验确定最优条数;
  • 使用transaction或者prepare插入,在本场景中优化效果不明显;
  • 使用多连接/多线程操作,速度上有优势,但是把握不好容易造成资源占用率过高,连接数太大也容易影响其他应用;
  • 写入更新是postgresql新特性,使用会造成一定的性能消耗(相对直接插入);
  • 读取数据时,使用COPY语句能够获得较好的性能;
  • ado.net dbreader对象由于不需要fill的过程,读取速度也较快(虽然赶不上COPY),也可优先考虑。
P.S.
  • 为什么不用mysql

没有最好的,只有最合适的,讲道理我也是挺喜欢用mysql的。使用postgresql的原因主要在于:
postgresql导入导出的sql指令“copy”直接支持Binary模式到stdin和stdout,如果程序想直接集成,那么用这个是比较方便的;相比较,mysql的sql语法(load data infile)并不支持到stdin或者stdout,导出可以通过mysqldump.exe实现,导入暂时没什么特别好的办法(mysqlimport或许可以)。
  • 相较于mysql缺点

postgresql使用copy导入的时候,如果目标表已经有数据,那么在有主键约束的表遇到错误时,COPY自动终止,而且可能导致不完全插入的情况,换言之,是不支持导入的过程进行update操作;mysql的load语法可以显式指定出错之后的动作(IGNORE/REPLACE),不会打断导入过程。
  • 其他

如果需要使用mysql从程序导入数据,可以考虑先通过程序导出到文件,然后借助文件进行导入,据说效率也要比insert高出不少。

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

- 澳门娱乐城
基于案例的 SQL 优化实战训练营

讲师:中电福富特级专家梁敬彬,参与本次课程培训,你将收获:
1. 能编写出较为高效的 SQL;
2. 能解决70%以上的数据库常见优化问题;
3. 能得到老师提供的高效的相关工具和解决方案;
4. 能举一反三,收获不仅仅是 SQL 优化。
现在购票享受8.8折优惠!
----------------------------------------
优惠时间:2019年3月20日前

大会官网>>
  

北京盛拓优讯信息技术有限公司. 版权所有 北京市公安局海淀分局网监中心备案编号:11010802020122
中国互联网协会会员  联系我们:huangweiwei@it168.com
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - - Archiver - 澳门娱乐城 - TOP