- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
Apache Parquet 的特点是:
最佳答案
我认为我可以描述的主要区别与面向记录的格式与面向列的格式有关。面向记录的格式是我们都习惯的格式——文本文件、分隔格式,如 CSV、TSV。 AVRO 比那些更酷,因为它可以随着时间的推移改变模式,例如从记录中添加或删除列。各种格式的其他技巧(特别是包括压缩)涉及格式是否可以拆分——也就是说,您能否从数据集中的任何位置读取记录块并仍然知道它的模式?但这里有更多关于 Parquet 等柱状格式的详细信息。
Parquet 和其他列格式可以非常有效地处理常见的 Hadoop 情况。在设计良好的关系数据库中,表(数据集)的列数通常比您预期的多得多——一百或两百列并不罕见。之所以如此,是因为我们经常使用 Hadoop 作为对关系格式中的数据进行非规范化的地方——是的,您会得到很多重复的值,很多表都被扁平化为一个。但是由于所有连接都已计算出来,因此查询变得容易得多。还有其他优势,例如保留实时状态数据。所以无论如何,在一个表中有一大堆列是很常见的。
假设有 132 列,其中一些是非常长的文本字段,每个不同的列一个接一个,每条记录可能使用 10K。
虽然从 SQL 的角度查询这些表很容易,但您通常希望仅基于这数百列中的少数几列来获取一定范围的记录。例如,您可能需要 2 月和 3 月销售额大于 500 美元的客户的所有记录。
要以行格式执行此操作,查询需要扫描数据集的每条记录。读取第一行,将记录解析为字段(列)并获取日期和销售额列,如果满足条件,则将其包含在结果中。重复。如果您有 10 年(120 个月)的历史,那么您正在阅读每条记录只是为了找到其中的 2 个月。当然,这是在年和月上使用分区的绝佳机会,但即便如此,您还是要读取和解析那两个月内每条记录/行的 10K 条记录,只是为了确定客户的销售额是否大于 500 美元。
在列格式中,记录的每一列(字段)与其他同类存储在一起,分布在磁盘上的许多不同块中——年份的列,月份的列,客户员工手册的列(或其他长文本),以及所有其他使这些记录如此庞大的所有其他人都在磁盘上各自独立的位置,当然还有用于销售的列。哎呀,日期和月份是数字,销售额也是——它们只是几个字节。如果我们只需要为每条记录读取几个字节来确定哪些记录与我们的查询匹配,那不是很好吗?柱状存储来拯救!
即使没有分区,扫描满足我们查询所需的小字段也非常快——它们都是按记录排序的,并且大小相同,因此磁盘寻找包含记录的数据检查要少得多。无需通读员工手册和其他长文本字段——只需忽略它们即可。因此,通过将列而不是行分组,您几乎总是可以扫描更少的数据。赢!
但是等等,它会变得更好。如果您的查询只需要知道这些值和更多值(假设 132 列中的 10 列)并且不关心员工手册列,一旦它选择了正确的记录返回,它现在只需要去回到渲染结果所需的 10 列,忽略数据集中 132 列中的其他 122 列。再次,我们跳过了很多阅读。
(注意:出于这个原因,在进行直接转换时,列格式是一个糟糕的选择,例如,如果您将所有两个表连接成一个大(ger)结果集,然后将其保存为新表,则源无论如何都会被完全扫描,因此在读取性能方面没有太多好处,并且由于列格式需要更多地记住内容的位置,因此它们比类似的行格式使用更多的内存)。
柱状的另一个好处是:数据分散。要获得单个记录,您可以让 132 个工作人员在 132 个数据块上的 132 个不同位置读取(和写入)数据。是的并行化!
现在关键在于:压缩算法在可以找到重复模式时效果会更好。您可以压缩 AABBBBBBCCCCCCCCCCCCCCCC
如 2A6B16C
但是 ABCABCBCBCBCCCCCCCCCCCCCC
不会变小(好吧,实际上,在这种情况下会变小,但相信我:-))。所以再一次,少读书。还有写作。
因此,我们为回答常见查询而读取的数据要少得多,并行读取和写入可能会更快,并且压缩往往会更好地工作。
当您的输入端很大时,Columnar 很棒,而您的输出是一个过滤后的子集:从大到小都很棒。当输入和输出大致相同时,就不那么有利了。
但在我们的案例中,Impala 执行了我们在 5、10、20 或 30 分钟内运行的旧 Hive 查询,并在几秒钟或一分钟内完成了大部分查询。
希望这至少有助于回答您的部分问题!
关于file - 与其他格式相比, Parquet 格式的优缺点是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36822224/
我想知道是否可以访问放在 tomcat 的 conf 文件夹中的文件。通常我会在这个文件中放置多个 webapp 的配置,在 war 之外。 我想使用类路径独立于文件系统。 我过去使用过 lib 文件
我有一个 PowerShell 脚本,它获取文件列表并移动满足特定条件的文件。为什么即使对象为空,foreach 循环也会运行? 我假设如果 $i 不存在,它就不会运行。但是如果 $filePath
我已将 BasicAccountRule.drl 放置在我的 Web 应用程序中,位置为:C:/workspace/exim_design/src/main/resources/rules/drl/i
我使用 File.open('file.txt').class 和 File.open('file.txt').readlines.class 以及前者进行了检查一个返回 File,后者返回 Arra
我正在尝试使用 FileOutputStream 删除文件,在其中写入内容后。这是我用来编写的代码: private void writeContent(File file, String fileC
我正在尝试使用 flink 和 python 批处理 api 测试 Wordcount 经典示例。我的问题是,将数据源从 env.from_elements() 修改为 env.read_text()
我正在尝试制作一个可以同时处理多个不同文件的程序。我的想法是制作一个包含 20 个 FILE* 的数组,以便在我达到此限制时能够关闭其中一个并打开请求的新文件。 为此,我想到了一个函数,它选择一个选项
我有两个文件A和B文件A: 976464 792992 文件B TimeStamp,Record1,976464,8383,ABCD 我想搜索文件 A 和文件 B 中的每条记录并打印匹配的记录。打印的
我有一些保存在 map 中的属性文件。示例: Map map = new HashMap<>(); map.put("1", "One"); map.put("2", "Two"); map.put(
我正在尝试找出一个脚本文件,该文件接受一个包含文件列表的文件(每一行都是一个文件路径,即 path/to/file)并将它们合并到一个文件中。 例如: list.text -- path/to/fil
为了使用 File.CreateText() 和 File.AppendText() 你必须: 通过调用这些方法之一打开流 写消息 关闭流 处理流 为了使用 File.AppendAllText()
使用rsync时,如何在使用--files-from参数复制时重命名文件?我有大约190,000个文件,在从源复制到目标时,每个文件都需要重命名。我计划将文件列表放在一个文本文件中传递给--files
我在非服务器应用程序中使用 Spring(只需从 Eclipse 中某个类的 main() 编译并运行它)。 我的问题是作为 new FileSystemXmlApplicationContext 的
QNX (Neutrino 6.5.0) 使用 ksh 的开源实现作为其 shell 。许多提供的脚本,包括系统启动脚本,都使用诸如 if ! test /dev/slog -ef /dev/slog
当我尝试打开从我的应用程序下载的 xls 文件时,出现此错误: excel cannot open the file because the file format or file extension
有一些相关的概念,即文件指针、流和文件描述符。 我知道文件指针是指向数据类型 FILE 的指针(在例如 FILE.h 和 struct_FILE.h 中声明)。 我知道文件描述符是 int ,例如成员
好吧,这应该很容易... 我是groovy的新手,我希望实现以下逻辑: def testFiles = findAllTestFiles(); 到目前为止,我想出了下面的代码,该代码可以成功打印所有文
我理解为什么以下内容会截断文件的内容: Get-Content | Out-File 这是因为 Out-File 首先运行,它会在 Get-Content 有机会读取文件之前清空文件。 但是当我尝
您好,我正在尝试将文件位置表示为变量,因为最终脚本将在另一台机器上运行。这是我尝试过的代码,然后是我得到的错误。在我看来,python 是如何添加“\”的,这就是导致问题的原因。如果是这种情况,我如何
我有一个只包含一行的输入文件: $ cat input foo bar 我想在我的脚本中使用这一行,据我所知有 3 种方法: line=$(cat input) line=$( input"...,
我是一名优秀的程序员,十分优秀!