首先本文不会讲得很系统, 可以理解为是1个练习, 从这个简单例子中, 我们会体会到分区表与非分区表的操作和效果的区别
准备测试数据
首先, 本人准备了一份csv file , 测试数据,
大概样子如下:
创建数据表并导入数据
我们首先基于这个csv file 去创建1个bq 的数据表
bigquery 是支持直接通过上传csv 去创建1个新的表的, 而这个表的schema 可以被autodetect, 甚至field type可以自动识别哦
命令:
bq load --autodetect --source_format=CSV DS2.supermarket_sales supermarket_sales.csv
这时表已经从创建好了, 我们检查下schema 和数据行数:
[gateman@manjaro-x13 chapter-01]$ bq show DS2.supermarket_sales
/home/gateman/devtools/google-cloud-sdk/platform/bq/bq.py:17: DeprecationWarning: 'pipes' is deprecated and slated for removal in Python 3.13
import pipes
Table jason-hsbc:DS2.supermarket_sales
Last modified Schema Total Rows Total Bytes Expiration Time Partitioning Clustered Fields Total Logical Bytes Total Physical Bytes Labels
----------------- ----------------------------------- ------------ ------------- ------------ ------------------- ------------------ --------------------- ---------------------- --------
23 Dec 22:10:31 |- Invoice_ID: string 1000 149402 149402 31765
|- Branch: string
|- City: string
|- Customer_type: string
|- Gender: string
|- Product_line: string
|- Unit_price: float
|- Quantity: integer
|- Tax_5_: float
|- Total: float
|- Date: date
|- Time: string
|- Payment: string
|- cogs: float
|- gross_margin_percentage: float
|- gross_income: float
|- Rating: float
可以简单地看出, 新创建的表行数是1000 行, 而且某些字段的类型已经被自动识别为 date, integer or float.
使用sql 基于这张非分区表创建另2张分区表
supermarket_sales_p, 基于Date 列做分区, 每一天1个表分区
create table DS2.supermarket_sales_p
PARTITION BY DATE
as
SELECT Branch, City, Customer_type, Product_line, Unit_price,
Quantity, Tax_5_, Total, Date, Time, Payment, gross_income
FROM DS2.supermarket_sales
没错, BQ 还支持用sql来创建分区表, 关键字就是 PARTITION BY DATE , 这里的DATE是列名。
我在上一篇文章已经讲过, 时间分区表,有4中类型, 分别是Hour, Day, Month, Year.
上面的sql 没有指定, 默认是按Day, 也就是每一天1个表分区!
supermarket_sales_p2, 基于Date 列做分区, 每1月1个表分区
create table DS2.supermarket_sales_p2
PARTITION BY DATE_TRUNC(Date, MONTH)
as
SELECT Branch, City, Customer_type, Product_line, Unit_price,
Quantity, Tax_5_, Total, Date, Time, Payment, gross_income
FROM DS2.supermarket_sales
这里 PARTITION BY DATE 改成 PARTITION BY DATE_TRUNC(Date, MONTH)
注意, 新的两个分区表比起原表是精简了一些列的, 相当灵活
好, 创建好之后我们检查下表结构和行数
[gateman@manjaro-x13 chapter-01]$ bq show DS2.supermarket_sales_p
/home/gateman/devtools/google-cloud-sdk/platform/bq/bq.py:17: DeprecationWarning: 'pipes' is deprecated and slated for removal in Python 3.13
import pipes
Table jason-hsbc:DS2.supermarket_sales_p
Last modified Schema Total Rows Total Bytes Expiration Time Partitioning Clustered Fields Total Logical Bytes Total Physical Bytes Labels
----------------- -------------------------- ------------ ------------- ------------ ------------------- ------------------ --------------------- ---------------------- --------
23 Dec 23:44:51 |- Branch: string 1000 105400 DAY (field: Date) 105400 343651
|- City: string
|- Customer_type: string
|- Product_line: string
|- Unit_price: float
|- Quantity: integer
|- Tax_5_: float
|- Total: float
|- Date: date
|- Time: string
|- Payment: string
|- gross_income: float
[gateman@manjaro-x13 chapter-01]$ bq show DS2.supermarket_sales_p2
/home/gateman/devtools/google-cloud-sdk/platform/bq/bq.py:17: DeprecationWarning: 'pipes' is deprecated and slated for removal in Python 3.13
import pipes
Table jason-hsbc:DS2.supermarket_sales_p2
Last modified Schema Total Rows Total Bytes Expiration Time Partitioning Clustered Fields Total Logical Bytes Total Physical Bytes Labels
----------------- -------------------------- ------------ ------------- ------------ --------------------- ------------------ --------------------- ---------------------- --------
23 Dec 23:48:37 |- Branch: string 1000 105400 MONTH (field: Date) 105400 28942
|- City: string
|- Customer_type: string
|- Product_line: string
|- Unit_price: float
|- Quantity: integer
|- Tax_5_: float
|- Total: float
|- Date: date
|- Time: string
|- Payment: string
|- gross_income: float
[gateman@manjaro-x13 chapter-01]$
注意观察分区信息, 1个按Day 分区, 一个按月分区. 行数都是1000
继续查看分区信息
SELECT *
FROM DS2.INFORMATION_SCHEMA.PARTITIONS
where table_name = 'supermarket_sales_p'
order by partition_id
table_catalog|table_schema|table_name |partition_id|total_rows|total_logical_bytes|total_billable_bytes|last_modified_time |storage_tie
-------------+------------+-------------------+------------+----------+-------------------+--------------------+-----------------------+-----------
jason-hsbc |DS2 |supermarket_sales_p|20190101 | 12| 1260| 1260|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190102 | 8| 840| 840|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190103 | 8| 836| 836|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190104 | 6| 633| 633|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190105 | 12| 1285| 1285|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190106 | 9| 925| 925|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190107 | 9| 953| 953|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190108 | 18| 1908| 1908|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190109 | 8| 840| 840|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190110 | 9| 950| 950|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190111 | 8| 839| 839|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190112 | 11| 1171| 1171|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190113 | 10| 1056| 1056|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190114 | 13| 1385| 1385|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190115 | 13| 1365| 1365|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190116 | 10| 1050| 1050|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190117 | 11| 1162| 1162|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190118 | 9| 943| 943|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190119 | 16| 1694| 1694|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190120 | 10| 1046| 1046|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190121 | 8| 822| 822|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190122 | 7| 733| 733|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190123 | 17| 1779| 1779|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190124 | 13| 1364| 1364|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190125 | 17| 1777| 1777|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190126 | 17| 1785| 1785|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190127 | 14| 1467| 1467|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190128 | 14| 1493| 1493|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190129 | 12| 1261| 1261|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190130 | 9| 972| 972|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190131 | 14| 1497| 1497|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190201 | 6| 635| 635|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190202 | 14| 1466| 1466|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190203 | 14| 1456| 1456|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190204 | 11| 1158| 1158|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190205 | 12| 1255| 1255|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190206 | 13| 1390| 1390|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190207 | 20| 2115| 2115|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190208 | 12| 1257| 1257|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190209 | 13| 1360| 1360|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190210 | 11| 1159| 1159|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190211 | 8| 841| 841|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190212 | 8| 839| 839|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190213 | 8| 858| 858|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190214 | 8| 839| 839|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190215 | 19| 2017| 2017|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190216 | 8| 846| 846|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190217 | 13| 1376| 1376|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190218 | 7| 728| 728|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190219 | 9| 954| 954|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190220 | 10| 1056| 1056|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190221 | 6| 619| 619|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190222 | 11| 1161| 1161|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190223 | 8| 850| 850|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190224 | 9| 951| 951|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190225 | 16| 1687| 1687|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190226 | 9| 951| 951|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190227 | 14| 1485| 1485|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190228 | 6| 629| 629|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190301 | 10| 1064| 1064|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190302 | 18| 1916| 1916|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190303 | 14| 1489| 1489|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190304 | 12| 1228| 1228|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190305 | 17| 1800| 1800|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190306 | 11| 1166| 1166|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190307 | 9| 949| 949|2023-12-23 23:44:51.313|ACTIVE
jason-hsbc |DS2 |supermarket_sales_p|20190308 | 11| 1164| 1164|2023-12-23 23:44:51.313|ACTIVE
SELECT *
FROM DS2.INFORMATION_SCHEMA.PARTITIONS
where table_name = 'supermarket_sales_p2'
order by partition_id
table_catalog|table_schema|table_name |partition_id|total_rows|total_logical_bytes|total_billable_bytes|last_modified_time |storage_tier|
-------------+------------+--------------------+------------+----------+-------------------+--------------------+-----------------------+------------+
jason-hsbc |DS2 |supermarket_sales_p2|201901 | 352| 37091| 37091|2023-12-23 23:48:37.508|ACTIVE |
jason-hsbc |DS2 |supermarket_sales_p2|201902 | 303| 31938| 31938|2023-12-23 23:48:37.508|ACTIVE |
jason-hsbc |DS2 |supermarket_sales_p2|201903 | 345| 36371| 36371|2023-12-23 23:48:37.508|ACTIVE |
可以看出supermarket_sales_p 已经存在很多个表分区, 1天1个分区, 而supermarket_sales_p2 只有3个分区, 对应3个月份, 而且也可以知道每个分区到底有多少个数据行
先查询原表并观察
我们可以看出, 原表的数据量两为145.9KB
当我们尝试查询 select * from 原表 时, BQ 已经提示会process 145.9KB , 也就是全表的数据量, 这个没什么问题
当我们尝试只检索某些列(就是上面两张分区表的列)时, 发现will process的数据量减少了,变成了102.93KB 这个也可以理解, 毕竟我们不想要查询所有列嘛
然后我们加上Date 列的filter , 只查询2月份的数据
如上图, 见到还是提示 102.93KB will be processed, 没有变化啊, 再想想也可以理解, BQ并没有索引, 所以还是检索全表才会找出DATE 在2月份的数据!
结下来我们先在web ui 上禁用缓存, 保证每次查询都是从磁盘去获得数据
在其他场景如何禁用缓存? 参考下文
https://cloud.google.com/bigquery/docs/cached-results#bq
接下来我们按button Run 去执行这个sql去检索非分区表 从查询job 的信息来看, 的确处理了102 kb data
而且从另外两张图来看, 的确处理了1000数据, 即使只返回了300多行, 但是收费是按1000行来收的
查询按日分区表 supermarket_sales_p
当我们写入sql时, web ui 已经提示will processed 的数据只有30多kb了!
因为加上了Date 这个字段, 数据只会在2月份的多个表分区里查找, skip了2月份之外的其他表分区。
然后我们执行查询, 查看执行信息, 的确是30KB ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/29c18cd21a78450fbc42f30c7ca1eee3.png)
再查看执行计划图 ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/2eeb23f9d8dc405aadc37ca5dea180dd.png) ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/2bbc76e8b10f4d63a350e162a217d821.png) 的确只process了303 行数据
值得注意的是, Wait 和 Read的时间效果都增加了
因为BQ 后台里会有多个进程同时去查询多个表分区, 而且需要wait 来整合查询的数据, 这里数据量小(1000k), 分区表的效率不高, 但是当数据量变大, 分区表的性能优势就出来了。
查询按月分区表 supermarket_sales_p2
当我们写入sql时, web ui 已经同样提示will processed 的数据只有30多kb了!
这里的查询只会 在1个表分区里查找, 因为此表是按月分区的
再查看执行计划图 ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/7d2101ebec6341eb867cfb2910341bef.png) 可以看出wait 只有1ms, 因为只有1个表分区查询嘛, 所以对这条sql来讲, 月分区效率更高
但是 日分区表会更灵活, 例如只查询 2月28 和 3月1号 的数据, 相信日分区表会有效率得多!