BigQuery 分区表简介和使用

大纲

在这里插入图片描述

什么是分区表

我们先看定义:

分区表是一种数据库表设计和管理技术,它将表中的数据划分为逻辑上的多个分区,每个分区包含一组特定的数据。每个分区都根据定义的分区键(通常是一个列或字段)的值进行分类,使得数据可以按照特定的逻辑规则进行划分和组织。

通过使用分区表,可以将大型表分解为更小的、可管理的部分,以提高查询性能、数据维护效率和存储资源的利用率。分区表的实现方式和语法可能因数据库管理系统而异,但基本概念和原则是相似的。





具体给个例子:

我有张table sales_details, 和一些测试数据, 如下:

select * from DS2.sales_detailsOrder_ID|Product                 |Quantity_Ordered|Price_Each|Order_Date|Purchase_Address                        |
--------+------------------------+----------------+----------+----------+----------------------------------------+
176565  |updated                 |               1|    1700.0|2019-04-24|915 Willow St, San Francisco, CA 94016  |
176565  |updated                 |               1|    1700.0|2019-04-24|915 Willow St, San Francisco, CA 94016  |
176565  |updated                 |               1|    1700.0|2019-04-24|915 Willow St, San Francisco, CA 94016  |
176565  |updated                 |               1|    1700.0|2019-04-24|915 Willow St, San Francisco, CA 94016  |
176565  |updated                 |               1|    1700.0|2019-04-24|915 Willow St, San Francisco, CA 94016  |
176565  |updated                 |               1|    1700.0|2019-04-24|915 Willow St, San Francisco, CA 94016  |
176609  |Apple Airpods Headphones|               1|     150.0|2019-04-11|267 11th St, Austin, TX 73301           |
176609  |Apple Airpods Headphones|               1|     150.0|2019-04-11|267 11th St, Austin, TX 73301           |
176609  |Apple Airpods Headphones|               1|     150.0|2019-04-11|267 11th St, Austin, TX 73301           |
176609  |Apple Airpods Headphones|               1|     150.0|2019-04-11|267 11th St, Austin, TX 73301           |
176609  |Apple Airpods Headphones|               1|     150.0|2019-04-11|267 11th St, Austin, TX 73301           |
176609  |Apple Airpods Headphones|               1|     150.0|2019-04-11|267 11th St, Austin, TX 73301           |
176617  |Apple Airpods Headphones|               1|     150.0|2019-04-25|319 8th St, Portland, OR 97035          |
176617  |Apple Airpods Headphones|               1|     150.0|2019-04-25|319 8th St, Portland, OR 97035          |
176617  |Apple Airpods Headphones|               1|     150.0|2019-04-25|319 8th St, Portland, OR 97035          |
176617  |Apple Airpods Headphones|               1|     150.0|2019-04-25|319 8th St, Portland, OR 97035          |
176617  |Apple Airpods Headphones|               1|     150.0|2019-04-25|319 8th St, Portland, OR 97035          |
176617  |Apple Airpods Headphones|               1|     150.0|2019-04-25|319 8th St, Portland, OR 97035          |
176591  |Apple Airpods Headphones|               1|     150.0|2019-04-21|600 Maple St, Austin, TX 73301          |
176591  |Apple Airpods Headphones|               1|     150.0|2019-04-21|600 Maple St, Austin, TX 73301          |
176591  |Apple Airpods Headphones|               1|     150.0|2019-04-21|600 Maple St, Austin, TX 73301          |
176591  |Apple Airpods Headphones|               1|     150.0|2019-04-21|600 Maple St, Austin, TX 73301          |

当这个表的数据量增大时, 去查询这个表的性能会变慢。

这时我们定下1个规则, 我们查询这个表时都必须加上1个filter 字段。 这个字段设成是Order_Date (字段类型是DATE)
我们查询时都加上这个filter 查询某1天or 某段时间内的数据, 例如

select * from DS2.sales_details where Order_Date = '2019-04-11'

如果用户场景符合上面的前提, 那么我们就可以为这个表做成分区表了

在这里插入图片描述
如上图, 我们可以利用Order_Date 做分区, 把整个table 以每一日创建1个分区。

那么当我们执行上面的sql

select * from DS2.sales_details where Order_Date = '2019-04-11'

那么它就会只在 2019-04-11的表分区里面查询, 避免了全表检索, 查询速度就大大加快了。

好了, 上面只是一些基本原理, 下面是一些常见问题。




1. 如果查询条件是1个区间, 例如 Order_Date >= ‘2019-04-11’, 分区表还有效吗?

有效, 这种情况下排除了 2019-04-11 之前的分区, 还是避免了全表检索, 这个查询会查询2019-04-11 之前的所有分区, 所以建议filter 加上下界
例如

select * from DS2.sales_details_p4 where Order_Date BETWEEN  '2019-04-24' and '2019-04-29'

这样这个sql只会 在某几个表分区查询, 而Big Query是支持并发在多个表分区里查询数据的。




2. 以每一日做1个分区, 会导致表分区过多?

BigQuery 用时间分区表的话, 还支持用 hour, month , year来分区!




3. 如果查询分区表不加上分区字段filter, 查询效率会更差?

没错, 如果上面的例子, sql里不加上Order_date filter 的话, sql会在所有的分区里查询数据, 效率会比非分区表更差! 所以创建分区表时要考虑清楚表的查询场景!




4. 如果查询sql 一定要加上分区字段filter, 为何不直接加个索引? 一样能大大加快查询速度。

的确, 为filter 字段加上索引更加省事也更常用。 这是1个好问题。

为了回答这个问题, 要列出下面几点

a. BigQuery 不是普通关系数据库, 它不支持索引, BQ 本身是通过分区和分桶, 然后在背后实现并发查询来提高速度的。
下面的point是对于其他数据库的

b. 对于传统关系数据库, 例如Oracle Mysql, 表大小在1GB以下的还是建议索引更高效, 表越大, 分区表优势越大!
c. 如果查询结果集范围相对较小, 使用索引会更合适
d. 查询结果集的范围涉及多个分区, 使用多个分区表更高效
e. 复杂查询下, 即使使用索引, 也会涉及很多子查询, 子查询的数据可能会占用临时表空间甚至内存。 使用分区表只会在某些物理介质里查询, 更高效
f.数据管理和维护:分区表可以更好地管理数据,使数据维护操作更高效。你可以针对特定的分区执行数据导入、删除或重组操作,而无需处理整个表。这对于大型数据集或频繁进行数据维护的情况下尤为重要。
g.存储和成本控制:分区表允许你根据数据的生命周期和访问模式应用不同的存储策略和成本控制措施。例如,你可以选择将较旧的分区存储在低成本的存储介质上,而将最近的分区存储在高性能的存储介质上。这可以帮助降低存储成本,同时保持查询性能。

但是对于BQ, 核心技术是多分区并发查询!




BigQuery 分区表类型

根据本码农分析, BQ 的分区表大概分3种类型

1.时间分区表 (time_partitioning)

这个种分区表必须指定1个时间类型的字段。 也就是这个字段的类型为必须是 DATE 和 Timestamp的一种

其中DATE 类型只包含日期, 没有时分秒信息
而TIMESTAMP包含时分秒甚至毫秒

而且分区的类型要选择下面的4种之一
Hour, Day, Month, Year

本文只会用时间分区表作为详细例子, 其他两种会简单带过




2. 区间分区表 (integer-range_partitioning)

区间分区表必须以1个 Integer类型字段作为分区字段。 (例如 id值)

而且还需要设定1个属性 range, 也就多大的值范围作1个分区

例如, 我有1个张很多学生的考试分数表
可以对分数(前提是整数) 作为分区字段

range 可以set称10
那么这个分数表就大概分成 10 个分区了。




3. 注入时间分区表 (ingestion-time_partitioning)

这种比较特别, 其实也是时间分区表的一种, 但是不必制定分区字段。
这种分区表会用 当前record 被插入到表的时间戳作为分区字段。

一旦这种分区表被创建, 就有1个伪列 _PARTITIONTIME or _PARTITIONDATE
可以获得当前record的首次插入表的时间
同样
也需要制定type
Hour, Day, Month, Year 的一种




创建 BigQuery 分区表

有多种 方法, 包括 bq 命令, sql, google api等
这里只介绍terraform

resource "google_bigquery_table" "sales_details_p" {dataset_id = google_bigquery_dataset.dataset1.dataset_idtable_id   = "sales_details_p"project    = var.project_iddeletion_protection = falseschema = <<EOF
[{"name": "Order_ID","type": "STRING"},{"name": "Product","type": "STRING"},{"name": "Quantity_Ordered","type": "INTEGER"},{"name": "Price_Each","type": "FLOAT"},{"name": "Order_Date","type": "DATE"},{"name": "Purchase_Address","type": "STRING"}
]
EOFtime_partitioning {type                     = "DAY"  # partitioning by Dayfield                    = "Order_Date"  # Use it as the partition field//expiration_ms            = 2592000000  # set the expired days to 30//require_partition_filter = true  # must use partition filter}
}

上面的terraform 就定义了1个分区表资源 sales_details_p, 它以Order_Date 作为分区字段
值得注意的是

  1. 分区字段, 例如上面的Order_date, 类型不能为String, 根据实际选择DATE OR TIMESTAMP
  2. expiration_ms 表示当前分区表的分区的过期日期(毫秒表示), 可以不设置, 后面会详解
  3. require_partition_filter 表示是否强制要求对这个分区表的查询加上分区表字段filter, 后面会详解

当表被创建后,可以用bq show 来查看该表的分区信息

[gateman@manjaro-x13 coding]$ bq show DS2.sales_details_p
/home/gateman/devtools/google-cloud-sdk/platform/bq/bq.py:17: DeprecationWarning: 'pipes' is deprecated and slated for removal in Python 3.13import pipes
Table jason-hsbc:DS2.sales_details_pLast modified               Schema              Total Rows   Total Bytes   Expiration      Time Partitioning      Clustered Fields   Total Logical Bytes   Total Physical Bytes   Labels  ----------------- ------------------------------ ------------ ------------- ------------ ------------------------- ------------------ --------------------- ---------------------- -------- 23 Dec 04:18:36   |- Order_ID: string            0            0                          DAY (field: Order_Date)                      0                                                    |- Product: string                                                                                                                                                       |- Quantity_Ordered: integer                                                                                                                                             |- Price_Each: float                                                                                                                                                     |- Order_Date: date                                                                                                                                                      |- Purchase_Address: string                                                                                                                                              [gateman@manjaro-x13 coding]$ 




查询 BigQuery 分区表

当分区表sales_details_p 创建好后, 我们把数据从 非分区表 sales_details 插入到 sales_details_p

INSERT INTO DS2.sales_details_p
(Order_ID, Product, Quantity_Ordered, Price_Each, Order_Date, Purchase_Address)
select Order_ID, Product, Quantity_Ordered, Price_Each,  PARSE_DATE('%Y-%m-%d', Order_Date) AS Order_Date, Purchase_Address 
from DS2.sales_details




查询时间分区表

很简单上面已经举过例子了, 只需要加上分区key的filter

select * from DS2.sales_details_p where Order_Date BETWEEN  '2019-04-24' and '2019-04-29'




查询区间分区表

一样, 例如
假设分区表 product 的分区字段是product_id (Interger)

select * from DS2.product  where product_id BETWEEN  1000 and 2000




查询注入时间分区表

假设分区表product 是注入时间分区表
则我们需要用伪列来作filter

select * from DS2.product  where _PARTITIONTIME BETWEEN  TIMESTAMP('2016-01-01') AND TIMESTAMP('2016-01-02')




管理BigQuery 分区表

获取分区表元数据

就是查看当前的分区表共有多少个表分区等信息
我们可以看查询 《Dataset》.INFORMATION_SCHEMA.PARTITIONS 这个系统表

SELECT table_name, partition_id, total_rows,*
FROM `DS2.INFORMATION_SCHEMA.PARTITIONS`
WHERE table_name = 'sales_details_p'table_name     |partition_id|total_rows|table_catalog|table_schema|table_name_1   |partition_id_1|total_rows_1|total_logical_bytes|total_billable_bytes|last_modified_time     |storage_tier|
---------------+------------+----------+-------------+------------+---------------+--------------+------------+-------------------+--------------------+-----------------------+------------+
sales_details_p|20190401    |         6|jason-hsbc   |DS2         |sales_details_p|20190401      |           6|                546|                 546|2023-12-23 04:23:42.439|ACTIVE      |
sales_details_p|20190411    |        30|jason-hsbc   |DS2         |sales_details_p|20190411      |          30|               2676|                2676|2023-12-23 04:23:42.439|ACTIVE      |
sales_details_p|20190421    |        18|jason-hsbc   |DS2         |sales_details_p|20190421      |          18|               1590|                1590|2023-12-23 04:23:42.439|ACTIVE      |
sales_details_p|20190417    |        12|jason-hsbc   |DS2         |sales_details_p|20190417      |          12|               1068|                1068|2023-12-23 04:23:42.439|ACTIVE      |
sales_details_p|20190419    |        12|jason-hsbc   |DS2         |sales_details_p|20190419      |          12|               1110|                1110|2023-12-23 04:23:42.439|ACTIVE      |
sales_details_p|20190430    |        30|jason-hsbc   |DS2         |sales_details_p|20190430      |          30|               2718|                2718|2023-12-23 04:23:42.439|ACTIVE      |
sales_details_p|20190407    |        24|jason-hsbc   |DS2         |sales_details_p|20190407      |          24|               2286|                2286|2023-12-23 04:23:42.439|ACTIVE      |
sales_details_p|20190429    |        12|jason-hsbc   |DS2         |sales_details_p|20190429      |          12|               1074|                1074|2023-12-23 04:23:42.439|ACTIVE      |
sales_details_p|20190415    |        18|jason-hsbc   |DS2         |sales_details_p|20190415      |          18|               1626|                1626|2023-12-23 04:23:42.439|ACTIVE      |
sales_details_p|20190403    |        12|jason-hsbc   |DS2         |sales_details_p|20190403      |          12|               1020|                1020|2023-12-23 04:23:42.439|ACTIVE      |
sales_details_p|20190425    |         6|jason-hsbc   |DS2         |sales_details_p|20190425      |           6|                540|                 540|2023-12-23 04:23:42.439|ACTIVE      |
sales_details_p|20190405    |        12|jason-hsbc   |DS2         |sales_details_p|20190405      |          12|               1140|                1140|2023-12-23 04:23:42.439|ACTIVE      |
sales_details_p|20190427    |        30|jason-hsbc   |DS2         |sales_details_p|20190427      |          30|               2790|                2790|2023-12-23 04:23:42.439|ACTIVE      |
sales_details_p|20190412    |        18|jason-hsbc   |DS2         |sales_details_p|20190412      |          18|               1554|                1554|2023-12-23 04:23:42.439|ACTIVE      |
sales_details_p|20190424    |        12|jason-hsbc   |DS2         |sales_details_p|20190424      |          12|               1008|                1008|2023-12-23 04:23:42.439|ACTIVE      |
sales_details_p|20190402    |        30|jason-hsbc   |DS2         |sales_details_p|20190402      |          30|               2646|                2646|2023-12-23 04:23:42.439|ACTIVE      |
sales_details_p|20190409    |        12|jason-hsbc   |DS2         |sales_details_p|20190409      |          12|                984|                 984|2023-12-23 04:23:42.439|ACTIVE      |
sales_details_p|20190420    |         6|jason-hsbc   |DS2         |sales_details_p|20190420      |           6|                552|                 552|2023-12-23 04:23:42.439|ACTIVE      |
sales_details_p|20190422    |         6|jason-hsbc   |DS2         |sales_details_p|20190422      |           6|                516|                 516|2023-12-23 04:23:42.439|ACTIVE      |
sales_details_p|20190410    |        12|jason-hsbc   |DS2         |sales_details_p|20190410      |          12|               1092|                1092|2023-12-23 04:23:42.439|ACTIVE      |
sales_details_p|20190428    |         6|jason-hsbc   |DS2         |sales_details_p|20190428      |           6|                570|                 570|2023-12-23 04:23:42.439|ACTIVE      |
sales_details_p|20190408    |         6|jason-hsbc   |DS2         |sales_details_p|20190408      |           6|                474|                 474|2023-12-23 04:23:42.439|ACTIVE      |
sales_details_p|20190418    |        18|jason-hsbc   |DS2         |sales_details_p|20190418      |          18|               1590|                1590|2023-12-23 04:23:42.439|ACTIVE      |
sales_details_p|20190404    |        24|jason-hsbc   |DS2         |sales_details_p|20190404      |          24|               2250|                2250|2023-12-23 04:23:42.439|ACTIVE      |
sales_details_p|20190426    |        12|jason-hsbc   |DS2         |sales_details_p|20190426      |          12|               1074|                1074|2023-12-23 04:23:42.439|ACTIVE      |
sales_details_p|20190416    |        12|jason-hsbc   |DS2         |sales_details_p|20190416      |          12|               1026|                1026|2023-12-23 04:23:42.439|ACTIVE      |

可以见到, 分区id (partition_id)就是日期




强制使用分区字段filter

就是上面提到的分区表属性 require_partition_filter
个人建议谨慎设置

设置为true的优点是, 强制所有其他开发人员写sql时加上分区字段filter, 否则会报错

SQL Error [100032] [HY000]: [Simba][BigQueryJDBCDriver](100032) Error executing query job. 
Message: Cannot query over table 'DS2.sales_details_p2' without a filter over column(s) 'Order_Date' that can be used for partition elimination

缺点是, 所有包括count等所有就和函数也需要加上filter, 否则失败, 而且无法在GCP console上预览数据, 有时难以用sql获得表的总体信息.




设置失效时间

就是expiration_ms , 用毫秒表示

注意失效时间是以分区字段的值开始计算

例如expiration_ms 设成30日的话,

当我在20231221 插入一条Order_Date 为20190622 的数据时, 你以为用 Order_date =‘20190622’ 能查到数据?

其实是 分区20190622 一旦创建就马上过期(从20190622 算起。。) 今天已经是2023年了

所以这种情况下会导致分区创建后被删除, 数据会丢失
即使使用 select * from table 不加上分区字段filter (没有设成require_partition_filter=true的话) 也是查不出该数据的…

所以谨慎设置, 个人建议不要设置这个属性, 默认是分区永不过期




删除某个表分区

如果向手动删除一些旧数据, 而想直接删除某个分区的话

总之这个操作很危险, 对应的sql也没找到

我们可以用bq 民令来实现
bq rm --table project_id:dataset.table$partition

例如:

[gateman@manjaro-x13 coding]$ bq rm --table 'DS2.sales_details_p$20190407'
/home/gateman/devtools/google-cloud-sdk/platform/bq/bq.py:17: DeprecationWarning: 'pipes' is deprecated and slated for removal in Python 3.13import pipes
rm: remove table 'jason-hsbc:DS2.sales_details_p$20190407'? (y/N) y
[gateman@manjaro-x13 coding]$ 

注意这个操作也是删除数据的操作!没事别删, BQ存储很便宜!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/293928.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uniapp中如何使用百度tts生成文字语音并播放

第一步先在百度云里面申请一个tts应用&#xff0c;这里默认你们都会了哈&#xff0c;申请完是这样的 第二步在manifest.json注册一下 第三步进项目,先获取token handleGetToken() {// client_id和client_secret就是百度API Key和Secret Keyuni.request({url: https://aip.ba…

DevOps系列文章 : 使用dpkg命令打deb包

创建一个打包的目录&#xff0c;类似rpmbuild&#xff0c;这里创建了目录deb_build mkdir deb_build目标 我有一个hello的二进制文件hello和源码hello.c, 准备安装到/opt/helloworld目录中 步骤 在deb_build目录创建一个文件夹用于存放我的安装文件 mkdir helloworld在he…

阿里云 ARMS 应用监控重磅支持 Java 21

作者&#xff1a;牧思 & 山猎 前言 今年的 9 月 19 日&#xff0c;作为最新的 LTS (Long Term Support) Java 版本&#xff0c;Java 21 正式 GA&#xff0c;带来了不少重量级的更新&#xff0c;详情请参考 The Arrival of Java 21 [ 1] 。虽然目前 Java 11 和 Java 17 都…

关于“Python”的核心知识点整理大全36

目录 13.4.4 向下移动外星人群并改变移动方向 game_functions.py alien_invasion.py 13.5 射杀外星人 13.5.1 检测子弹与外星人的碰撞 game_functions.py alien_invasion.py 13.5.2 为测试创建大子弹 13.5.3 生成新的外星人群 game_functions.py alien_invasion.py …

Java之LinkedList核心源码解读

LinkedList核心源码解读 LinkedList 是一个基于双向链表实现的集合类&#xff0c;经常被拿来和 ArrayList 做比较 LinkedList 插入和删除元素的时间复杂度&#xff1f; 头部插入/删除&#xff1a;只需要修改头结点的指针即可完成插入/删除操作&#xff0c;因此时间复杂度为 O…

LLM之RAG实战(八)| 使用Neo4j和LlamaIndex实现多模态RAG

人工智能和大型语言模型领域正在迅速发展。一年前&#xff0c;没有人使用LLM来提高生产力。时至今日&#xff0c;很难想象我们大多数人或多或少都在使用LLM提供服务&#xff0c;从个人助手到文生图场景。由于大量的研究和兴趣&#xff0c;LLM每天都在变得越来越好、越来越聪明。…

论文润色的注意事项有哪些 papergpt

大家好&#xff0c;今天来聊聊论文润色的注意事项有哪些&#xff0c;希望能给大家提供一点参考。 以下是针对论文重复率高的情况&#xff0c;提供一些修改建议和技巧&#xff0c;可以借助此类工具&#xff1a; 标题&#xff1a;论文润色的注意事项――确保论文质量与表达的关键…

从零开发短视频电商 在AWS上SageMaker部署模型自定义日志输入和输出示例

从零开发短视频电商 在AWS上SageMaker部署模型自定义日志输入和输出示例 怎么部署自定义模型请看&#xff1a;从零开发短视频电商 在AWS上用SageMaker部署自定义模型 都是huaggingface上的模型或者fine-tune后的。 为了适配jumpstart上部署的模型的http输入输出&#xff0c;我…

华为 WATCH GT 4 跨越想象的边界,打造智慧生活新体验

颜值新高度&#xff0c;健康更全面&#xff01;华为 WATCH GT 4 颜值超能打&#xff0c;表盘随心定义&#xff0c;健康管理再升级身体状况更有数&#xff0c;超长续航给足安全感。跨越想象的边界&#xff0c;打造智慧生活新体验&#xff01;

ModuleNotFoundError: No module named ‘tensorflow‘

直接运行pip install tensorflow安装成功之后&#xff0c;发现版本是tensorflow2.15.0 python的版本是3.9版本 导入包&#xff1a;import tensorflow 打包xxx.exe,调用之后提示错误 ModuleNotFoundError: No module named tensorflow 最后发现特定的python的版本对应特定的t…

生物系统学中的进化树构建和分析R工具包V.PhyloMaker2的介绍和详细使用

V.PhyloMaker2是一个R语言的工具包&#xff0c;专门用于构建和分析生物系统学中的进化树&#xff08;也称为系统发育树或phylogenetic tree&#xff09;。以下是对V.PhyloMaker2的一些基本介绍和使用说明&#xff1a; 论文介绍&#xff1a;V.PhyloMaker2: An updated and enla…

Ubuntu及Docker 安装rabbitmq

安装ubuntu 前 先暴露端口&#xff1a; 5672 用于与mq服务器通信用 15672 管理界面使用的端口 docker命令&#xff1a;docker run -itd --name ubuntu -p 5672:5672 -p 15672:15672 ubuntu 进入docker : docker exec -it ubuntu /bin/bash 步骤&#xff1a; 1. 更新安装源…