hive内部分区表(ORC格式)新增字段后出现的问题

本文解决Hive ORC格式分区表新增字段后查询异常、分区删除失败及SparkSQL查询失败等问题,涉及更新元数据库CD_ID、禁止矢量查询及修改字段类型等方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

hive内部分区表(ORC格式)在新增字段后出现的问题:

1、在新增字段后的新分区内查询数据 正常,在新增字段后的旧分区内查询数据 异常

2、分区删不掉,一直卡着不动

3、在执行插入分区的动作后,数据文件中已经有新字段值了,但是在查询的时候新字段的值还是显示为null

4、利用sparkSQL查询历史分区部分字段,出现无法查询现象

      异常:java.lang.ClassCastException: org.apache.hadoop.io.Text cannot be cast to org.apache.hadoop.io.LongWritable

1-3 问题原因:

当我们修改hive表结构以后,mysql中元数据库中的SDS中该hive表对应的CD_ID会改变,但是该hive表旧的分区下面对应的CD_ID还是原来表的CD_ID.

如果使用动态分区插入的数据,每个分区的CD_ID都不相同

1-3 解决方案:

测试表:int_optimize_bidrequest,分区字段:date、hour  (假设在2017-06-12进行的新增表字段操作)

查看表的CD_ID:select CD_ID from SDS where LOCATION='hdfs://tercel/user/hive/warehouse/dsp.db/int_optimize_bidrequest',(假设新的CD_ID值为105749)
该hive表的新增字段后的新分区的CD_ID:SELECT CD_ID FROM SDS WHERE LOCATION LIKE '%hdfs://tercel/user/hive/warehouse/dsp.db/int_optimize_bidrequest/date=2017-06-14/hour=01%'(CD_ID值为105749,等于主表的CD_ID)
该hive表的新增字段后的旧分区的CD_ID:SELECT CD_ID FROM SDS WHERE LOCATION LIKE '%hdfs://tercel/user/hive/warehouse/dsp.db/int_optimize_bidrequest/date=2017-06-10/hour=01%''(CD_ID值为71806)
我们需要更新一下现有分区的CD_ID的值为表CD_ID的值:
UPDATE SDS SET CD_ID=105749 WHERE LOCATION LIKE '%hdfs://tercel/user/hive/warehouse/dsp.db/int_optimize_bidrequest/date%'

然后我们再去查询一下表int_optimize_bidrequest,字段的值就可以正常的显示出来了。

注意问题:

如果出现hive表不能修改,可直接更改hive元表

1、 SELECT * FROM COLUMNS_V2 WHERE CD_ID=105749  ORDER BY INTEGER_IDX

2、INSERT INTO COLUMNS_V2 (CD_ID,COLUMN_NAME,TYPE_NAME,INTEGER_IDX) VALUES(105749,'adx','string',0)

3、禁止设置矢量查询

#矢量查询(Vectorized query) 每次处理数据时会将1024行数据组成一个batch进行处理,而不是一行一行进行处理,这样能够显著提高执行速度。

 

set hive.vectorized.execution.enabled = false;

4、如果在hive中执行 desc dsp.int_optimize_bidrequest依旧卡着不动,很有可能是表处于被锁的状态

执行 show locks dsp.int_optimize_bidrequest 查看表的状态,如果为 Exclusive(排他锁),继续执行 unlock tabledsp.int_optimize_bidrequest命令解锁

3 问题原因:

       由于HIVE有数据类型自动转换的功能,在建表的时候都创建为了String类型,但修改或增加字段后会出现字段类型匹配不上的现象。因为在ORC存储数据时为了节约存储空间,都会有明确的数据类型。在用HIVE查询会自动兼容,但是用第三方工具查询时(如SparkSQL)会出现类型转换失败的问题。

3 解决方案

 

修改问题表字段类型

Alter table stg.xh_temp_netinfo_d  change column st  st  BIGINT

<think>好的,用户想了解如何在Hive中创建分区表。首先,我需要回忆Hive分区表的相关知识。记得分区表是通过将数据按某个或几个字段的值分成不同的目录存储,这样可以提高查询效率,尤其是在处理大数据时,避免全表扫描。 根据用户提供的引用内容,特别是引用[2]中的语法结构,创建分区表需要在CREATE TABLE语句中使用PARTITIONED BY子句。分区字段在表中并不作为实际的数据列存在,而是作为目录结构。比如,按日期分区的话,每个日期会生成一个子文件夹。 接下来,我需要考虑如何给出一个具体的示例。比如,用户可能想知道如何按地区(如city)和日期(如dt)进行分区。这里要注意分区的顺序,先按city再按dt的话,目录结构会是city=beijing/dt=20230101这样的形式。 然后,用户可能需要插入数据到分区表的例子。这时候需要使用INSERT INTO语句,并指定分区字段的值。需要注意的是,动态分区和静态分区的区别。示例中使用的是静态分区,直接指定值,而动态分区则需要设置相关参数,比如hive.exec.dynamic.partition.mode=nonstrict。 还要提到分区的优势,比如提升查询性能和管理数据。引用[3]提到分区在存储层面表现为子文件夹,支持多重分区,所以例子中用了两个分区字段来说明这点。 另外,用户可能遇到的问题,比如分区字段不能与表字段重复,或者分区字段的数据类型需要正确指定。这些注意事项应该在步骤中说明,避免常见错误。 最后,生成相关问题时要围绕分区表的使用场景、管理操作、优化方法等方面展开,帮助用户进一步学习。比如如何添加新分区、分区表的性能优化、动态分区的使用等。 总结一下,回答的结构应该是先介绍概念,然后给出语法和示例,接着说明数据插入方法,最后注意事项和相关问题。需要确保所有步骤符合Hive的语法规范,并且引用提供的参考资料来支持内容。</think>### Hive 分区表创建教程 在 Hive 中创建分区表是通过`PARTITIONED BY`子句实现的,其核心作用是将数据按指定字段值分类存储。以下是具体操作步骤: #### 1. 基础语法 ```sql CREATE TABLE 表名 ( 列名1 数据类型, 列名2 数据类型, ... ) PARTITIONED BY (分区字段1 数据类型, 分区字段2 数据类型) STORED AS ORC; -- 可选存储格式 ``` *注意:分区字段不能与表中已有字段重复*[^2] #### 2. 创建示例 创建按城市和日期分区的订单表: ```sql CREATE TABLE orders ( order_id STRING, amount DOUBLE, customer_id STRING ) PARTITIONED BY (city STRING, dt STRING) ROW FORMAT DELIMITED FIELDS TERMINATED BY ','; ``` 此时HDFS中会生成路径结构:`/user/hive/warehouse/orders/city=北京/dt=20230101`[^3] #### 3. 数据加载 静态分区插入示例: ```sql INSERT INTO TABLE orders PARTITION (city='北京', dt='20230101') SELECT order_id, amount, customer_id FROM temp_orders; ``` #### 4. 分区优势 - 查询优化:执行`WHERE city='北京'`时自动跳过无关分区 - 数据管理:可单独删除/添加分区(`ALTER TABLE orders DROP PARTITION (dt='20230101')`) - 存储优化:支持按分区设置不同存储策略 #### 5. 注意事项 - 分区字段会作为虚拟列出现在表结构中 - 建议分区层级不超过3级 - 避免产生过多小分区(建议每个分区≥1GB) - 使用`SHOW PARTITIONS orders;`查看分区信息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值