首页 文章 精选 留言 我的

精选列表

搜索[数据处理],共9360篇文章
优秀的个人博客,低调大师

性能提升数倍 IBM光谱计算搞定海量数据处理

一直以来,IBM给人呈现出的形象就是高大上的前瞻者,在大数据等方面一直引领着行业发展。近两年IBM还提出了认知商业概念,将企业级计算相关应用推向了高潮。 Spectrum Computing(光谱计算)是IBM刚刚推出的产品,它是一套全新智能资源与工作负载管理软件,能使企业更为轻松地挖掘数据价值,提升性能密集型大数据分析工作负载和机器学习的速度。该技术将为各行各业的客户提供支持,比如通过基因组排序实现更好的癌症治疗、辅助工程师设计出具有夺冠实力的一级方程式赛车、帮助银行家面向潜在客户推出个性化金融服务。 IBM整合Platform推出光谱计算 IBM软件定义解决方案大中华区销售经理 周立旸 Platform Computing之前笔者也曾接触过,这是一家技术实力很强的企业,在分布式计算等方面有着较深造诣。当时给人留下深刻印象的案例就是空中客车以及各个证券交易所的分布式系统,非常强大。而在2011年IBM正式收购了Platform Computing,这些年来将其技术不断融入IBM,使其成为了现在的Spectrum Computing(光谱计算)。 谈到光谱计算,IBM软件定义解决方案大中华区销售经理周立旸认为:传统来说,往往计算和存储是分离的,随着新的认知型应用的发展,不仅需要水平扩展,实际上也是应对整个认知商业的大环境。我们不仅要存储、管理海量的数据,让这些数据真正产生价值,还是要对它进行有效应用和分析。在去年发布光谱存储家族软件定义存储的基础上,我们在今天发布Spectrum Computing,实现软件定义的平台,有助于用户、企业在软件定义存储的基础上通过软件定义计算对海量的非结构化数据进行充分的利用,从而为企业的数字化转型找到更多的价值点,也找到新的应用。 Spectrum Computing包含六大产品,提供强大整合管理能力 产品方面,据周立旸介绍光谱存储有六大产品,这六大产品可以单独作用,也可以互相结合,Spectrum Computing目前包含三大产品。一个是LSF,主要针对高性能和批处理应用,高性能计算在国内外很多制造业、电子行业、生命科学领域用的比较多,同样在企业里面也有大量批处理应用。 此外还有Symphony,主要针对大数据和高性能分析,一方面完全兼容所有Hadoop的接口,另一方面提供了自己的API,使得高性能分析应用不经过修改、只要经过这个API就可以在一台机器乃至几千台机器上动态地运行。 IBM最新发布的光谱计算中还包含全新的Spectrum Conductor。在应用方面,针对了所有新型的云应用,像现在Spark内存计算方式非常流行,还有新的NoSQL数据库,针对这些云类型的应用,需要有一个工作负载管理的产品。Conductor是可扩展的融合架构,不仅仅是水平扩展的软件定义的组件,它当中整合了软件定义计算和软件定义存储,这包含了分布式文件系统,也包含了怎么样把内部的数据和外部的云数据整合起来进行管理的能力。这也是整个产品家族里面最新的一个产品。 未来,随着软件定义计算和软件定义存储的融合,IBM会增加更多的整合方案,推出更多针对水平扩展的软件定义环境的融合架构的产品。 软件定义让企业用户更容易实现扩展 周立旸认为软件定义已经变得越来越重要。随着企业数据量越来越多,不是单一工具就能够满足它认知商业的所有需要,可能需要各种各样的工具,需要不同的NoSQL的DB,需要内存计算、流计算对实时信息作处理。每一种新型工具都是水平扩展的架构,对任何一个企业来讲都有五个到十个工具,可能对应采用传统的方式就要五个到十个集群。集群本身的管理使用起来比单一系统复杂。随着认知商业、云计算应用的发展,企业内部集群应用越来越多,必然需要一种新型方式,把很多个集群整合成一个,或者把一个云或者一个集群当做很多个集群来用,这正好是软件定义基础架构所解决的问题。 据周立旸介绍,IBM也有这样的客户,无论是国内、国外,国外有个金融保险公司,在一个平台上运行了30多种不同的分布式应用,包括开源软件,包括商用的客户行为分析、SPSS应用等。对于用户来讲,这种方式比自己建立很多个不同的集群更好,每个集群随着业务的增长还需要不断地扩展,不同的集群还需要访问下面的数据,这个复杂性的话随着应用的增加而成一个脊柱型的增长,必然最后会采用软件定义的方式来管理所有分布式的应用。 科研、金融和电信开始应用光谱计算 应用方面,周立旸表示目前光谱计算在金融业、电信应用比较多,电信行业中数据量非常大,要用水平扩展的架构,因此很多用大数据分析的平台也在用光谱计算。生命科学行业,前段时间IBM刚刚办了一个会,请了清华大学国家蛋白质中心代表和大家分享。随着生命科学的发展,它的数据量增加的非常多。清华大学的电子显微镜,大概数据产生速度是一天产生20多TB的数据,所以一定要通过水平扩展的架构。由于清华大学一栋教学楼的空间有限,现在这个集群要分在几个不同的楼层里面来,所以采用了IBM的软件定义方式进行生命科学的分析平台。未来随着认知商业的普及,相信行业覆盖面会越来越多、越来越广。 看似高大上的光谱计算目前已经开始应用到各个行业领域,采用软件定义方式,能够把整个集群平均利用率提升到90%甚至更高,有五到六倍效率提升。光谱计算给企业级应用带来了质的飞跃,新技术带来新革命,IBM继续着他的探索之路。 本文作者:云中子 来源:51CTO

优秀的个人博客,低调大师

海量数据处理利器greenplum——初识

简介及适用场景 如果想在数据仓库中快速查询结果,可以使用greenplum。 Greenplum数据库也简称GPDB。它拥有丰富的特性: 第一,完善的标准支持:GPDB完全支持ANSI SQL 2008标准和SQL OLAP 2003 扩展;从应用编程接口上讲,它支持ODBC和JDBC。完善的标准支持使得系统开发、维护和管理都大为方便。而现在的 NoSQL,NewSQL和Hadoop 对 SQL 的支持都不完善,不同的系统需要单独开发和管理,且移植性不好。 第二,支持分布式事务,支持ACID。保证数据的强一致性。 第三,做为分布式数据库,拥有良好的线性扩展能力。在国内外用户生产环境中,具有上百个物理节点的GPDB集群都有很多案例。 第四,GPDB是企业级数据库产品,全球有上千个集群在不同客户的生产环境运行。这些集群为全球很多大的金融、政府、物流、零售等公司的关键业务提供服务。 第五,GPDB是Greenplum(现在的Pivotal)公司十多年研发投入的结果。GPDB基于PostgreSQL 8.2,PostgreSQL 8.2有大约80万行源代码,而GPDB现在有130万行源码。相比PostgreSQL 8.2,增加了约50万行的源代码。 第六,Greenplum有很多合作伙伴,GPDB有完善的生态系统,可以与很多企业级产品集成,譬如SAS,Cognos,Informatic,Tableau等;也可以很多种开源软件集成,譬如Pentaho,Talend 等。 greenplum起源 Greenplum最早是在10多年前(大约在2002年)出现的,基本上和Hadoop是同一时期(Hadoop 约是2004年前后,早期的Nutch可追溯到2002年)。当时的背景是: 互联网行业经过之前近10年的由慢到快的发展,累积了大量信息和数据,数据在爆发式增长,这些海量数据急需新的计算方式,需要一场计算方式的革命; 传统的主机计算模式在海量数据面前,除了造价昂贵外,在技术上也难于满足数据计算性能指标,传统主机的Scale-up模式遇到了瓶颈,SMP(对称多处理)架构难于扩展,并且在CPU计算和IO吞吐上不能满足海量数据的计算需求; 分布式存储和分布式计算理论刚刚被提出来,Google的两篇著名论文发表后引起业界的关注,一篇是关于GFS分布式文件系统,另外一篇是关于MapReduce 并行计算框架的理论,分布式计算模式在互联网行业特别是收索引擎和分词检索等方面获得了巨大成功。 下图就是GFS的架构 总体架构 greenplum的总体架构如下: 数据库由Master Severs和Segment Severs通过Interconnect互联组成。 Master主机负责:建立与客户端的连接和管理;SQL的解析并形成执行计划;执行计划向Segment的分发收集Segment的执行结果;Master不存储业务数据,只存储数据字典。 Segment主机负责:业务数据的存储和存取;用户查询SQL的执行。 greenplum使用mpp架构。 基本体系架构 master节点,可以做成高可用的架构 master node高可用,类似于hadoop的namenode和second namenode,实现主备的高可用。 segments节点 并行管理 对于数据的装载和性能监控。 并行备份和恢复。 数据访问流程,数据分布到不同颜色的节点上 查询流程分为查询创建和查询分发,计算后将结果返回。 对于存储,将存储的内容分布到各个结点上。 对于数据的分布,分为hash分布和随机分布两种。 均匀分布的情况: 总结 GPDB从开始设计的时候就被定义成数据仓库,如果是olap的应用,可以尝试使用GPDB。

优秀的个人博客,低调大师

Parquet 存、DuckDB 查、Polars 转:数据处理的三道工序

上个月我接了个活儿。一个电商客户手里有几年的用户行为日志——浏览、下单、退款、点广告,全堆在 JSONL 文件里。 客户想做用户分层模型。我兴冲冲把日志往模型里一塞,模型直接翻脸。 原因很简单:模型要的是"这个用户买了几次、花了多少钱、活跃了几天"这种**用户级特征**。原始日志是"谁在哪一秒干了啥"的零散事件。两者中间差着一层。 那一刻我明白了:原始事件到模型特征之间,缺的不是模型,是一条管道。 我花了 5 天,用 DuckDB + Polars + Parquet 把这条管道搭了起来。今天先讲最底层的认知:三个工具各管一摊,谁也替代不了谁。 ## 一、三个工具,三个角色 先给一句话定义: - **Parquet:负责存的**。一种面向分析场景的列式存储格式。 - **DuckDB:负责查的**。一个嵌入式 SQL 引擎,不用起服务,对着文件就能查。 - **Polars:负责转的**。一个高性能 DataFrame 工具,干清洗、转换、特征工程。 类比钉死:它们仨就像一家小饭馆的**仓库、点单台、后厨**。仓库管存货(Parquet),点单台管你要什么菜(SQL 查询),后厨管把食材做成能上桌的菜(Polars 清洗转换)。饭馆不是一个角色在扛,管道也一样。 ### Parquet 为什么不能用 CSV 凑合 CSV 是**按行**存:一行一条记录,读的时候整行搬进来。Parquet 是**按列**存:user_id 一列、amount 一列、timestamp 一列。 好处直接看表: | 对比项 | CSV(行式) | Parquet(列式) | | ---- | --------- | ----------- | | 读取方式 | 整行读 | 只读需要的列 | | 压缩 | 一般 | 更好 | | 类型 | 全是字符串 | 保留真实类型 | | 分析查询 | 慢 | 快 | | 重复解析 | 每次都要解析字符串 | 不用 | 如果模型只要 `user\_id`、`amount`、`country` 三列,CSV 也得把 `email`、`phone`、`browser` 整行搬进来。Parquet 直接跳过这些列,拎你要的走。 这就是列式存储的价值:**用多少,读多少。** ### DuckDB:不用开机的 SQL 传统数据库要先起服务、建连接、建表。DuckDB 不用,直接在 Python 里跑: ``` import duckdb connection = duckdb.connect() ``` 它最擅长的,是直接对着 Parquet 文件写 SQL: ``` result = connection.execute(""" SELECT user\_id, amount FROM read\_parquet('data/bronze/events.parquet') WHERE event = 'purchase' AND amount > 0 """).fetchall() ``` 注意这里没有"先把 Parquet 读成 DataFrame"。是 DuckDB 直接查文件。它像是图书馆里那个不用你办卡、对着书架就能报出答案的管理员。 ### Polars:数据清洗的流水线 Polars 干的是脏活:类型转换、日期处理、按用户聚合。代码是表达式风格,不是逐行 for 循环。 ``` import polars as pl events = pl.read\_parquet("data/bronze/events.parquet") cleaned = events.with\_columns( pl.col("amount").cast(pl.Float64), pl.col("timestamp").str.to\_datetime(), ) ``` 这句的意思是:把 amount 转成浮点数,timestamp 转成真正的日期类型。一行写完,Polars 在底层并行处理,比你手写循环快得多。 ## 二、JSON 和 JSONL,别再混了 这个项目踩的第一个概念坑,就是这俩。 **JSON** 整个文件必须是一个合法结构,通常是个数组: ``` [ {"user\_id": 1001, "event": "purchase"}, {"user\_id": 1002, "event": "page\_view"} ] ``` **JSONL**(也叫 NDJSON)每行一个独立 JSON: ``` {"user\_id": 1001, "event": "purchase"} {"user\_id": 1002, "event": "page\_view"} ``` 类比:JSON 像一整本装订好的书,你得捧着整本读;JSONL 像收据打印机吐出来的纸条,一件一件往下接。 为什么日志用 JSONL?因为它: - 一行就是一条事件,新事件直接追加; - 可以逐行读,不用整文件加载进内存; - 某一行坏了,定位也快。 电商日志是持续产生的,JSONL 正好对得上这个节奏。 ## 三、目录怎么分层 我按"数据成熟度"建了四层目录,灵感来自数据湖的 bronze / silver / gold(铜 / 银 / 金)分层: | 目录 | 存什么 | 类比 | | ------------- | ------------- | ------- | | `data/raw` | 原始日志,绝不改 | 刚挖出来的矿石 | | `data/bronze` | 统一转成的 Parquet | 粗炼后的锭 | | `data/silver` | 清洗后的业务明细 | 精炼金属 | | `data/gold` | 用户级模型特征 | 成品零件 | 第 1 天我没急着写业务,先把环境跑通。用 `uv` 管依赖,不用系统 Python: ``` import duckdb import polars as pl import pyarrow import pydantic def main() -> None: print("DuckDB:", duckdb.\_\_version\_\_) print("Polars:", pl.\_\_version\_\_) print("PyArrow:", pyarrow.\_\_version\_\_) print("Pydantic:", pydantic.\_\_version\_\_) if \_\_name\_\_ == "\_\_main\_\_": main() ``` 运行就一句: ``` uv run python main.py ``` 这条没业务逻辑的脚本,价值在确认三件事:依赖装好了、uv 能跑、四个库都能导入。地基稳了,后面才敢往上盖。 ## 心得 5 天下来我最深的体会一句话: > **Parquet、DuckDB、Polars 不是谁替代谁,而是管道里三个分工明确的工位。** 存归存、查归查、转归转。以前我图省事,什么都往 Pandas + CSV 里塞,结果文件越攒越大、查询越来越慢。分清楚"存储、查询、转换"三件事,代码反而清爽了。 下篇我打算写 Bronze 层怎么把 JSONL 落进 Parquet,以及 DuckDB 怎么在文件上直接筛出购买事件。你平时处理数据,是 Pandas 一把梭,还是会像这样把存储、查询、转换拆开?评论区聊聊你踩过的坑。

优秀的个人博客,低调大师

C# SIMD编程实践:工业数据处理性能优化案例

性能奇迹的开始 想象一下这样的场景:一台精密的工业扫描设备每次检测都会产生200万个浮点数据,需要我们计算出最大值、最小值、平均值和方差来判断工件是否合格。使用传统的C#循环处理,每次计算需要几秒钟时间,严重影响生产线效率。 但是,通过SIMD优化后,同样的计算只需要几十毫秒! 这不是魔法,这是现代CPU并行计算能力的体现。今天,我们就来揭秘这个性能奇迹背后的技术原理。 什么是SIMD?为什么它这么快? SIMD(Single Instruction, Multiple Data) 是现代CPU的一项关键特性,翻译过来就是"单指令,多数据"。 传统处理 vs SIMD处理 想象你要给8个人发工资: 传统方式(标量处理): for (int i = 0; i &lt; 8; i++) { salary[i] = baseSalary[i] * 1.1f; // 一次处理一个 } SIMD方式(向量处理): // AVX2能一次处理8个浮点数! Vector256<float> base = Avx.LoadVector256(baseSalaryPtr); Vector256<float> multiplier = Vector256.Create(1.1f); Vector256<float> result = Avx.Multiply(base, multiplier); SIMD就像是把单核CPU变成了一个"8核并行计算器"(AVX2,2013年随第四代酷睿处理器推出;2015年AMD开始跟进),一条指令可以同时处理多个数据。 实战案例:200万数据点的统计计算 让我们看看如何将SIMD应用到实际的工业场景中。 场景描述 - 数据量:200万个float类型的测量点 - 计算需求:最大值、最小值、平均值、方差 - 性能要求:毫秒级响应,支持生产线实时检测 核心优化策略 1. 内存映射文件 + 批处理 这个不属于SIMD的范畴,但对这种结构化数据读取的场景是非常的实用。 // 使用内存映射文件避免频繁IO using var mmap = MemoryMappedFile.CreateFromFile(fileStream, null, 0, MemoryMappedFileAccess.Read, HandleInheritability.None, false); // 批处理:一次处理8192个数据点 const int batchSize = 8192; var valueBuffer = new float[batchSize]; 2. AVX2指令集:一次处理8个浮点数 性能提升的核心,从单行道变成八车道。 private static unsafe BatchStats ProcessBatchAvx(float[] values, int count) { fixed (float* ptr = values) { int vectorSize = Vector256<float>.Count; // 8个float // 初始化SIMD寄存器 Vector256<float> minVec = Avx.LoadVector256(ptr); Vector256<float> maxVec = minVec; Vector256<float> sumVec = Vector256<float>.Zero; Vector256<float> sumSqVec = Vector256<float>.Zero; // 向量化循环:一次处理8个数据 for (int i = vectorSize; i &lt;= count - vectorSize; i += vectorSize) { Vector256<float> data = Avx.LoadVector256(ptr + i); minVec = Avx.Min(minVec, data); // 并行求最小值 maxVec = Avx.Max(maxVec, data); // 并行求最大值 sumVec = Avx.Add(sumVec, data); // 并行累加 sumSqVec = Avx.Add(sumSqVec, Avx.Multiply(data, data)); // 平方和 } // 水平归约:将向量结果合并为标量 float min = HorizontalMin(minVec); float max = HorizontalMax(maxVec); double sum = HorizontalSum(sumVec); double sumSq = HorizontalSum(sumSqVec); return new BatchStats { Min = min, Max = max, Sum = sum, SumSquares = sumSq, Count = count }; } } 3. 优雅的降级策略 万一客户的环境不支持AVX2指令集怎么办,先降到SSE4.1(推出于2008年,也是Intel一马当先,AMD在2011年跟进),四车道也比单行道好。 private static BatchStats ProcessBatch(float[] values, int count) { // 智能选择最优的处理方式 if (Avx.IsSupported &amp;&amp; count &gt;= Vector256<float>.Count * 2) { return ProcessBatchAvx(values, count); // AVX2: 8x并行 } else if (Sse.IsSupported &amp;&amp; count &gt;= Vector128<float>.Count * 2) { return ProcessBatchSse(values, count); // SSE: 4x并行 } else { return ProcessBatchScalar(values, count); // 传统标量处理 } } SIMD的核心概念深度解析 1. 向量寄存器 现代CPU提供了专门的向量寄存器,这就为多个浮点数的“一次性处理”提供了物理基础: - SSE: 128位寄存器,可存储4个float - AVX: 256位寄存器,可存储8个float - AVX-512: 512位寄存器,可存储16个float 2. 水平归约(Horizontal Reduction) 当向量计算完成后,需要将向量中的多个值合并为一个标量结果,这是我们本次用到的最重要的SIMD指令,封装在.net的Vector128中: [MethodImpl(MethodImplOptions.AggressiveInlining)] private static float HorizontalMin(Vector256<float> vec) { // 将256位向量分解为两个128位向量 Vector128<float> lower = vec.GetLower(); // [a,b,c,d] Vector128<float> upper = vec.GetUpper(); // [e,f,g,h] Vector128<float> min128 = Sse.Min(lower, upper); // [min(a,e), min(b,f), min(c,g), min(d,h)] // 进一步归约:通过shuffle指令重排和比较 Vector128<float> shuf = Sse.Shuffle(min128, min128, 0b10110001); Vector128<float> min1 = Sse.Min(min128, shuf); shuf = Sse.Shuffle(min1, min1, 0b01001110); Vector128<float> min2 = Sse.Min(min1, shuf); return min2.ToScalar(); // 返回最终的标量结果 } 3. 数据对齐的重要性 SIMD虽好,也不能滥用。这个指令对内存对齐有严格要求: AVX指令要求32字节对齐 未对齐的内存访问会导致性能大幅下降 // 使用fixed确保指针稳定性,避免GC移动对象 fixed (float* ptr = values) { Vector256<float> data = Avx.LoadVector256(ptr + i); // 高效的对齐加载 } 性能对比:数据说话 基于200万浮点数的实际测试结果: 处理方式 处理时间 加速比 吞吐量 传统循环 2.1秒 1x 95万点/秒 | AVX优化 | 480毫秒 | 5x | 522万点/秒 | 结论:AVX优化相比传统方法实现了5倍的性能提升! C# SIMD编程的其他注意点 1. 硬件特性检测 如果你不能确定测试和生产环境是否支持这些新的指令集,可以运行以下代码做个测试。 Console.WriteLine($"AVX支持: {Avx.IsSupported}"); Console.WriteLine($"AVX2支持: {Avx2.IsSupported}"); Console.WriteLine($"SSE支持: {Sse.IsSupported}"); Console.WriteLine($"向量大小: {Vector256<float>.Count}"); 2. 安全的unsafe代码 对于这些涉及到内存的优化操作,需要将其包装在unsafe方法中,而且尽可能减少这部分的代码量,不推荐融入其他逻辑代码。 private static unsafe BatchStats ProcessBatchAvx(float[] values, int count) { // 使用fixed固定数组,防止GC移动 fixed (float* ptr = values) { // SIMD操作... } // 离开fixed块后,GC可以正常管理内存 } 3. 边界条件处理 用户的输入不一定是32的整数倍,所以,我们需要对余数做额外的处理,在确保对齐的前提下,不遗漏任何数据。 // 处理不能被向量大小整除的剩余元素 int vectorSize = Vector256<float>.Count; int i = 0; // 向量化主循环 for (i = 0; i &lt;= count - vectorSize; i += vectorSize) { ... } // 处理剩余元素 for (; i &lt; count; i++) { // 标量处理剩余的1-7个元素 } 4. JIT编译优化 在编译层面上,我们也可以做一些事情。实测效果不大,但工作量也不多。推荐还是带上。 [MethodImpl(MethodImplOptions.AggressiveInlining)] private static float HorizontalSum(Vector256<float> vec) { // AggressiveInlining确保JIT将小方法内联,避免函数调用开销 } 适用场景与注意事项 马斯洛讲到“当你手里只有锤子的时候,看什么都像钉子”,SIMD也是一把锤子。所以,我们得对SIMD做个总结,避免滥用。 SIMD适用的场景: - 大规模数值计算:统计分析、信号处理、图像处理 - 数据密集型操作:数组变换、矩阵运算 - 实时性要求高:游戏引擎、实时渲染 - 科学计算:物理仿真、机器学习推理 需要注意的问题: - 硬件兼容性:老CPU可能不支持AVX指令 - 内存对齐:不对齐的数据会影响性能 - 分支预测:条件判断会降低SIMD效率 - 调试困难:SIMD代码调试相对复杂 除了这次的技术验证,我们还在活字格低代码开发平台的“嵌入式向量库”插件中应用了这项技术。实现了大幅超越Faiss FlatIndexL2的性能表现,为构建AI智能体的低代码开发者们提供了新选择。 最后,请记住:性能优化不是奢侈品,而是现代软件开发的必需品。

优秀的个人博客,低调大师

如何使用GaussDB(DWS)的本地临时表进行数据处理

本文分享自华为云社区《GaussDB(DWS)临时表系列 - 本地临时表》,作者: acydy 。 GaussDB(DWS) 从8.2.1版本后支持三种形式的临时表:本地临时表、Volatile临时表、全局临时表。本文先介绍DWS的本地临时表功能。 本地临时表特点:表定义和数据都是会话相关,其他会话看不到本会话创建的本地临时表。元数据会持久化到系统表,集群节点异常出错可以支持RETRY。 语法与使用 CREATE [LOCAL] { TEMPORARY | TEMP } TABLE [ IF NOT EXISTS ] table_name ({ column_name data_type [ compress_mode ] [ COLLATE collation ] [ column_constraint [ ... ] ] | table_constraint | LIKE source_table [ like_option [...] ] } [, ... ]) [ WITH ( {storage_parameter = value} [, ... ] ) ] [ ON COMMIT { PRESERVE ROWS | DELETE ROWS } ] 建表时需要指定TEMP或者TEMPORARY,表示创建本地临时表。 ON COMMIT { PRESERVE ROWS | DELETE ROWS } ON COMMIT选项决定在事务中执行创建临时表操作,当事务提交时,此临时表的后续操作。 PRESERVE ROWS(缺省值):提交时不对临时表做任何操作,临时表及其表数据保持不变。建议使用此种类型。 DELETE ROWS:提交时删除临时表中数据。 其他部分与普通表相同。 gaussdb=# create temp table tmp1(a int,b int); NOTICE: The 'DISTRIBUTE BY' clause is not specified. Using round-robin as the distribution mode by default. HINT: Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column. CREATE TABLE 临时表可以与非临时表同名。如果同名,优先级临时表高于非临时表。 gaussdb=# create temp table tmp1(a int,b int); NOTICE: The 'DISTRIBUTE BY' clause is not specified. Using round-robin as the distribution mode by default. HINT: Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column. CREATE TABLE gaussdb=# insert into tmp1 values(1,1); INSERT 0 1 gaussdb=# create table tmp1(a int,b int); NOTICE: The 'DISTRIBUTE BY' clause is not specified. Using round-robin as the distribution mode by default. HINT: Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column. CREATE TABLE gaussdb=# select *from tmp1; a | b ---+--- 1 | 1 (1 row) gaussdb=# select *from public.tmp1; a | b ---+--- (0 rows) 视图:基于临时表创建的视图是临时视图。 postgres=# create view tmp_v1 as select *from tmp1; NOTICE: view "tmp_v1" will be a temporary view CREATE VIEW 使用场景 复杂业务逻辑使用本地临时表拆分 如果业务SQL语句过于复杂,可以使用本地临时表将执行的中间结果缓存下来,从而将复杂业务逻辑拆分成多个较简单语句。简单语句的统计信息更为准备,且拆分后的业务更易于维护。 支持CN节点出现异常。 GaussDB(DWS) 是一款分布式架构的数据库。有多个Coordinator(CN),关系对等。客户端可以连接任意一个CN。CN上存有表的元数据信息。在执行DDL时,会在所有DN上进行元数据的同步,保证数据一致性。如果某个CN出现异常,会导致创建表、删除表等操作执行失败,进而导致整个作业执行失败。 在这种场景,可以使用本地临时表。本地临时表只在当前会话可见。执行本地临时表的创建、ALTER、删除等操作时,只会在当前CN进行元数据的修改。这样可以不受其他CN节点异常的影响,保证业务使用连续性。 原理 临时表在元数据上与普通表的区别是临时表由于在其他会话不可见,所以会建在一个只属于当前会话的schema。本会话第一次创建临时表时会同时建立这个会话的schema。每一个会话的临时schema都不同。 会话1: gaussdb=# create temp table tmp1(a int,b int); NOTICE: The 'DISTRIBUTE BY' clause is not specified. Using round-robin as the distribution mode by default. HINT: Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column. CREATE TABLE gaussdb=# \d+ tmp1 Table "pg_temp_coordinator1_65_3_140257888512760.tmp1" Column | Type | Modifiers | Storage | Stats target | Description --------+---------+-----------+---------+--------------+------------- a | integer | | plain | | b | integer | | plain | | Has OIDs: no Distribute By: ROUND ROBIN Location Nodes: ALL DATANODES Options: orientation=row, compression=no: 会话2, 查询不到tmp1表。 gaussdb=# select * from tmp1; ERROR: relation "tmp1" does not exist LINE 1: select * from tmp1; ^ 临时schema的命名规则:pg_temp_Coordinator名_timelineID_全局自增ID_threadID Coordinator名:CN名称,隔离不同CN创建的schema。 timelineID:在节点重启后会增加,用于判断此schema是否已经无效。 全局自增ID:单个CN上自增ID。同一个CN不用会话自增ID不同。 元数据:本地临时表的relpersistence标识是’t’。 gaussdb=# select relname, relpersistence from pg_class where relname = 'tmp1'; relname | relpersistence ---------+---------------- tmp1 | t 数据清理: 会话正常退出 会话正常退出时, 本地临时表的表定义和数据都会被删除。无法再访问原来的数据。 会话异常退出或者当前CN或者某个DN节点异常时。 出现异常时,节点的元数据和数据不会被立即删除。 GaussDB(DWS)依赖组件gs_clean工具进行本地临时表的自动定期清理。保证数据再一段周期后得到清理,防止空间持续膨胀。 CN Retry CN Retry功能开启时会为临时表数据记录日志,为保证数据一致性,在使用临时表时不建议切换CN Retry开关状态,保持使用临时表的会话中CN Retry开关始终处于打开状态或者关闭状态。 在打开CN Retry时,DN节点异常重启,临时表的数据可以保证不丢失。DN重启后,仍可以访问之前的会话。 如果希望临时表不记录日志: set max_query_retry_times = 0; 使用约束 如果上层应用,使用了连接池机制连接GaussDB(DWS),在使用临时表时,强烈建议将连接归还连接池之前,将临时表主动删除,避免造成连接未断开导致的数据异常。或者使用命令DISCARD TEMP清理会话的临时表信息。 扩容时忽略本地临时表。 不支持gs_dump 本地临时表。 点击关注,第一时间了解华为云新鲜技术

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册