Managing partitioned tables

This document describes how to manage partitioned tables in BigQuery.

Note: The information inManaging tables alsoapplies to partitioned tables.

Get partition metadata

You can get information about partitioned tables in the following ways:

Getting partition metadata usingINFORMATION_SCHEMA views

When you query theINFORMATION_SCHEMA.PARTITIONS view, the query resultscontain one row for each partition. For example, the following query lists allof the table partitions in the dataset namedmydataset:

SELECTtable_name,partition_id,total_rowsFROM`mydataset.INFORMATION_SCHEMA.PARTITIONS`WHEREpartition_idISNOTNULL

For more information,seeINFORMATION_SCHEMA.PARTITIONS.

Getting partition metadata using meta-tables

In legacy SQL, you can get metadata about table partitions by querying the__PARTITIONS_SUMMARY__ meta-table.Meta-tables are read-only tables thatcontain metadata.

Query the__PARTITIONS_SUMMARY__ meta-table as follows:

#legacySQLSELECTcolumnFROM[dataset.table$__PARTITIONS_SUMMARY__]
Note: GoogleSQL does not support thepartition decorator separator ($), so you cannot query__PARTITIONS_SUMMARY__ in GoogleSQL.

The__PARTITIONS_SUMMARY__ meta-table has the following columns:

ValueDescription
project_idName of the project.
dataset_idName of the dataset.
table_idName of the time-partitioned table.
partition_idName (date) of the partition.
creation_timeThe time at which the partition was created, in milliseconds since January 1, 1970 UTC.
last_modified_timeThe time at which the partition was last modified, in milliseconds since January 1, 1970 UTC.

At a minimum, to run a query job that uses the__PARTITIONS_SUMMARY__ meta-table, you must be grantedbigquery.jobs.create permissions andbigquery.tables.getData permissions.

For more information on IAM roles in BigQuery, seeAccess control.

Set the partition expiration

When you create a table partitioned by ingestion time or time-unit column, youcan specify a partition expiration. This setting specifies how longBigQuery keeps the data in each partition. The setting applies toall partitions in the table, but is calculated independently for each partitionbased on the partition time.

A partition's expiration time is calculated from the partition boundary in UTC.For example, with daily partitioning, the partition boundary is at midnight(00:00:00 UTC). If the table's partition expiration is 6 hours, then eachpartition expires at 06:00:00 UTC the following day. When a partition expires,BigQuery deletes the data in that partition.

You can also specify adefault partition expirationat the dataset level. If you set the partition expiration on a table, thenthe value overrides the default partition expiration. If you don't specify anypartition expiration (on the table or dataset), then partitions never expire.

Note: Integer-range partitioned tables don't support partition expirationtimes.

If you set a table expiration, that value takes precedence over the partitionexpiration. For example, if the table expiration is set to 5 days, and thepartition expiration is set to 7 days, then the table and all partitions in itare deleted after 5 days.

At any point after a table is created, you can update the table's partitionexpiration. The new setting applies to all partitions in that table, regardlessof when they were created. Existing partitions expire immediately if they areolder than the new expiration time. Similarly, if data is being copied orinserted to a table partitioned by time-unit column, any partitions older thanpartition expiration configured for the table are expired immediately.

When a partition expires, BigQuery deletes that partition.The partition data is retained in accordance withtimetravel andfail-safe policies, and can bechargedfor, depending on yourbilling model. Until then, the partition counts for purposes oftable quotas. To delete a partitionimmediately, you canmanually delete the partition.

Update the partition expiration

To update a partitioned table's partition expiration:

Console

You cannot update the partition expiration in the Google Cloud console.

SQL

Use theALTER TABLE SET OPTIONS statement.The following exampleupdates the expiration to 5 days. To remove the partition expiration for atable, setpartition_expiration_days toNULL.

  1. In the Google Cloud console, go to theBigQuery page.

    Go to BigQuery

  2. In the query editor, enter the following statement:

    ALTERTABLEmydataset.mytableSETOPTIONS(-- Sets partition expiration to 5 dayspartition_expiration_days=5);

  3. ClickRun.

For more information about how to run queries, seeRun an interactive query.

bq

Issue thebq update command with the--time_partitioning_expirationflag. If you are updating a partitioned table in a project other than yourdefault project, add the project ID to the dataset name in the followingformat:project_id:dataset.

bqupdate\--time_partitioning_expirationinteger_in_seconds\--time_partitioning_typeunit_time\project_id:dataset.table

Where:

  • integer is the default lifetime (in seconds) for the table'spartitions. There is no minimum value. The expiration time evaluates tothe partition's date plus the integer value. If you specify0, thepartition expiration is removed, and the partitionnever expires. Partitions with no expiration must be manually deleted.
  • unit_time is eitherDAY,HOUR,MONTH, orYEAR, basedon the table's partitioning granularity. This value must match thegranularity that you set when you created the table.
  • project_id is your project ID.
  • dataset is the name of the dataset that contains the tableyou're updating.
  • table is the name of the table you're updating.

Examples:

Enter the following command to update the expiration time of partitions inmydataset.mytable to 5 days (432000 seconds).mydataset is in yourdefault project.

bq update --time_partitioning_expiration 432000 mydataset.mytable

Enter the following command to update the expiration time of partitions inmydataset.mytable to 5 days (432000 seconds).mydataset is inmyotherproject, not your default project.

bq update \--time_partitioning_expiration 432000 \myotherproject:mydataset.mytable

API

Call thetables.patchmethod and use thetimePartitioning.expirationMs property to update thepartition expiration in milliseconds. Because thetables.update methodreplaces the entire table resource, thetables.patch method is preferred.

Set partition filter requirements

When you create a partitioned table, you can require that all queries on thetable must include a predicate filter (aWHERE clause) that filters on thepartitioning column. This setting can improve performance and reduce costs,because BigQuery can use the filter to prune partitions thatdon't match the predicate. This requirement also applies to queries on views andmaterialized views that reference the partitioned table.

For information on adding theRequire partition filter option when youcreate a partitioned table, seeCreating partitioned tables.

If a partitioned table has theRequire partition filter setting, then everyquery on that table must include at least one predicate that only references thepartitioning column. Queries without such a predicate return the followingerror:

Cannot query over table 'project_id.dataset.table' without afilter that can be used for partition elimination.

For more information, seeQuerying partitioned tables.

Update the partition filter requirement

If you don't enable theRequire partition filter option when you create thepartitioned table, you can update the table to add the option.

Console

You cannot use the Google Cloud console to require partition filters aftera partitioned table is created.

SQL

Use theALTER TABLE SET OPTIONS statementto update the partition filter requirement. The followingexample updates the requirement totrue:

  1. In the Google Cloud console, go to theBigQuery page.

    Go to BigQuery

  2. In the query editor, enter the following statement:

    ALTERTABLEmydataset.mypartitionedtableSETOPTIONS(require_partition_filter=true);

  3. ClickRun.

For more information about how to run queries, seeRun an interactive query.

bq

To update a partitioned table to require partition filters by using the bq command-line tool,enter thebq update command and supply the--require_partition_filterflag.

To update a partitioned table in a project other than your default project,add the project ID to the dataset in the following format:project_id:dataset.

For example:

To updatemypartitionedtable inmydataset in your default project,enter:

bqupdate--require_partition_filtermydataset.mytable

To updatemypartitionedtable inmydataset inmyotherproject,enter:

bqupdate--require_partition_filtermyotherproject:mydataset.mytable

API

Call thetables.patchmethod and set therequirePartitionFilter property totrue to requirepartition filters. Because thetables.update method replaces the entiretable resource, thetables.patch method is preferred.

Java

Before trying this sample, follow theJava setup instructions in theBigQuery quickstart using client libraries. For more information, see theBigQueryJava API reference documentation.

To authenticate to BigQuery, set up Application Default Credentials. For more information, seeSet up authentication for client libraries.

importcom.google.cloud.bigquery.BigQuery;importcom.google.cloud.bigquery.BigQueryException;importcom.google.cloud.bigquery.BigQueryOptions;importcom.google.cloud.bigquery.Table;// Sample to update require partition filter on a table.publicclassUpdateTableRequirePartitionFilter{publicstaticvoidrunUpdateTableRequirePartitionFilter(){// TODO(developer): Replace these variables before running the sample.StringdatasetName="MY_DATASET_NAME";StringtableName="MY_TABLE_NAME";updateTableRequirePartitionFilter(datasetName,tableName);}publicstaticvoidupdateTableRequirePartitionFilter(StringdatasetName,StringtableName){try{// Initialize client that will be used to send requests. This client only needs to be created// once, and can be reused for multiple requests.BigQuerybigquery=BigQueryOptions.getDefaultInstance().getService();Tabletable=bigquery.getTable(datasetName,tableName);table.toBuilder().setRequirePartitionFilter(true).build().update();System.out.println("Table require partition filter updated successfully");}catch(BigQueryExceptione){System.out.println("Table require partition filter was not updated \n"+e.toString());}}}

Copy a partitioned table

The process for copying a partitioned table is the same as the process forcopying a standard table. For more information, seeCopying a table.

When you copy a partitioned table, note the following:

  • Copying a partitioned table to a new destination table
    All of the partitioning information is copied with the table. The newtable and the old table will have identical partitions.
  • Copying a non-partitioned table into an existing partitioned table
    This operation is only supported for ingestion-time partitioning.BigQuery copies the source data into the partition thatrepresents the current date. This operation is not supported for time-unitcolumn-partitioned or integer-range partitioned tables.
  • Copying a partitioned table into another partitioned table
    The partition specifications for the source and destination tables mustmatch.
  • Copying a partitioned table into a non-partitioned table
    The destination table remains unpartitioned.
  • Copying multiple partitioned tables

    If you copy multiple source tables into a partitioned table in the samejob, the source tables can't contain a mixture of partitioned andnon-partitioned tables.

    If all of the source tables are partitioned tables, the partitionspecifications for all source tables must match the destination table'spartition specification.

  • Copying a partitioned table that has aclustering specification

    If you copy into a new table, all of the clustering information is copiedwith the table. The new table and the old table will have identicalclustering.

    If you copy into an existing table, then the cluster specifications for thesource and destination tables must match.

When you copy to an existing table, you can specify whether to append oroverwrite the destination table.

Copy individual partitions

You can copy the data from one or more partitions to another table.

Note: The required permissions are the same as forcopying a table.

Console

Copying partitions is not supported by the Google Cloud console.

bq

To copy a partition, use the bq command-line tool'sbq cp (copy)command with a partition decorator ($date) such as$20160201.

Optional flags can be used to control the write disposition of thedestination partition:

  • -a or--append_table appends the data from the source partition to anexisting table or partition in the destination dataset.
  • -f or--force overwrites an existing table or partition in thedestination dataset and doesn't prompt you for confirmation.
  • -n or--no_clobber returns the following error message if the table orpartition exists in the destination dataset:Table '<var>project_id:dataset.table</var> or <var>table$date</var>'already exists, skipping. If-n is not specified, the default behavioris to prompt you to choose whether to replace the destination table orpartition.
  • --destination_kms_key is the customer-managed Cloud KMS keyused to encrypt the destination table or partition.

Thecp command does not support the--time_partitioning_field or--time_partitioning_type flags. You cannot use a copy job to convert aningestion-time partitioned table into a partitioned table.

--destination_kms_key is not demonstrated here. SeeProtecting data with Cloud KMS keysfor more information.

If the source or destination dataset is in a project other than your defaultproject, add the project ID to the dataset names in the following format:project_id:dataset.

(Optional) Supply the--location flag and set the value to yourlocation.

bq--location=locationcp\-a-f-n\project_id:dataset.source_table$source_partition\project_id:dataset.destination_table$destination_partition

Where:

  • location is the name of your location. The--location flag isoptional. For example, if you are using BigQuery in theTokyo region, you can set the flag's value toasia-northeast1. You canset a default value for the location using the.bigqueryrc file.
  • project_id is your project ID.
  • dataset is the name of the source or destination dataset.
  • source_table is the table you're copying.
  • source_partition is the partition decorator of the sourcepartition.
  • destination_table is the name of the table in the destinationdataset.
  • destination_partition is the partition decorator of thedestination partition.

Examples:

Note: The partition decorator separator ($) is a special variable in theunix shell. You might have to escape the decorator when you use the command-line tool. The following examples escape the partition decorator:mydataset.table\$20160519,'mydataset.table$20160519'.

Copying a partition to a new table

Enter the following command to copy the January 30, 2018 partition frommydataset.mytable to a new table —mydataset.mytable2.mydatasetis in your default project.

bq cp -a 'mydataset.mytable$20180130' mydataset.mytable2

Copying a partition to a non-partitioned table

Enter the following command to copy the January 30, 2018 partition frommydataset.mytable to a non-partitioned table —mydataset2.mytable2. The-a shortcut is used to append the partition'sdata to the non-partitioned destination table. Both datasets are in yourdefault project.

bq cp -a 'mydataset.mytable$20180130' mydataset2.mytable2

Enter the following command to copy the January 30, 2018 partition frommydataset.mytable to a non-partitioned table —mydataset2.mytable2. The-f shortcut is used to overwrite thenon-partitioned destination table without prompting.

bq --location=US cp -f 'mydataset.mytable$20180130' mydataset2.mytable2

Copying a partition to another partitioned table

Enter the following command to copy the January 30, 2018 partition frommydataset.mytable to another partitioned table —mydataset2.mytable2. The-a shortcut is used to append the partition'sdata to the destination table. Since no partition decorator is specified onthe destination table, the source partition key is preserved and the data iscopied to the January 30, 2018 partition in the destination table. You canalso specify a partition decorator on the destination table to copy data toa specific partition.mydataset is in your default project.mydataset2is inmyotherproject, not your default project.

bq --location=US cp \-a \'mydataset.mytable$20180130' \myotherproject:mydataset2.mytable2

Enter the following command to copy the January 30, 2018 partition frommydataset.mytable to the January 30, 2018 partition of anotherpartitioned table —mydataset2.mytable2. The-f shortcut is usedto overwrite the January 30, 2018 partition in the destination tablewithout prompting. If no partition decorator is used, all data in thedestination table is overwritten.mydataset is in your default project.mydataset2 is inmyotherproject, not your default project.

bq cp \-f \'mydataset.mytable$20180130' \'myotherproject:mydataset2.mytable2$20180130'

Enter the following command to copy the January 30, 2018 partition frommydataset.mytable to another partitioned table —mydataset2.mytable2.mydataset is in your default project.mydataset2is inmyotherproject, not your default project. If there is data in thedestination table, the default behavior is to prompt you to overwrite.

bq cp \'mydataset.mytable$20180130' \myotherproject:mydataset2.mytable2
Note: Thebq cp command with a partition decorator works on column-basedpartitions in which the source partition and destination partition areidentical. Thebq cp command also works on ingestion-time based partitionswhere the partition represents either the same time unit or a coarser timeunit that contains the source partition. For example, if$20180130 is thesource partition decorator, valid destination partition decorators include$20180130,$201801, and$2018. To copy a column-based partition to acompletely different partition decorator or to a time-unit partition withfiner granularity, use anINSERT SELECTstatement.

To copy multiple partitions, specify them as a comma-separated list:

bqcp\'mydataset.mytable$20180130,mydataset.mytable$20180131'\myotherproject:mydataset.mytable2

API

Call thejobs.insertmethod, and configure acopy job. (Optional) Specify your region in thelocation property in thejobReference section of thejob resource.

Specify the following properties in your job configuration:

  • Enter the source dataset, table, and partition in thesourceTablesproperty.
  • Enter the destination dataset and table in thedestinationTableproperty.
  • Use thewriteDisposition property to specify whether to append oroverwrite the destination table or partition.

To copy multiple partitions, enter the source partitions (including thedataset and table names) in thesourceTables property.

Delete a partition

You can delete an individual partition from a partitioned table. However, youcan't delete the special__NULL__ or__UNPARTITIONED__ partitions.

You can onlydelete one partition at a time.

Note: The required permissions are the same as fordeleting a table.

You can delete a partition by specifying the partition's decorator unless it isone of the twospecial partitions.

To delete a partition in a partitioned table:

Console

Deleting partitions is not supported by the Google Cloud console.

SQL

If aqualifyingDELETE statementcovers all rows in a partition,BigQuery removes the entire partition. This removal is donewithout scanning bytes or consuming slots. The following example of aDELETE statement covers the entire partition of a filter on the_PARTITIONDATE pseudocolumn:

  1. In the Google Cloud console, go to theBigQuery page.

    Go to BigQuery

  2. In the query editor, enter the following statement:

    DELETEmydataset.mytableWHERE_PARTITIONDATEIN('2076-10-07','2076-03-06');

  3. ClickRun.

For more information about how to run queries, seeRun an interactive query.

bq

Use thebq rm command with the--table flag (or-t shortcut) andspecify the partition decorator to delete a specific partition.

bqrm--tableproject_id:dataset.table$partition

Where:

  • project_id is your project ID. If omitted, your default projectis used.
  • dataset is the name of the dataset that contains the table.
  • table is the name of the table.
  • partition is the partition decorator of the partition you'redeleting.

Partition decorators have the following format, depending on the type ofpartitioning:

  • Hourly partition:yyyymmddhh. Example:$2016030100.
  • Daily partition:yyyymmdd. Example:$20160301.
  • Monthly partition:yyyymm. Example:$201603.
  • Yearly partition:yyyy. Example:$2016.
  • Integer range partition: Start of the partition range. Example:$20.

The bq command-line tool prompts you to confirm the action. To skip the confirmation,use the--force flag (or-f shortcut).

Note: The partition decorator separator ($) is a special variable in theunix shell. You might have to escape the decorator when you use the command-line tool. The following examples escape the partition decorator:mydataset.table\$20160519,'mydataset.table$20160519'.

Examples:

Delete the partition for March 1, 2016 in a daily partitioned table namedmydataset.mytable in your default project:

bq rm --table 'mydataset.mytable$20160301'

Delete the partition for March, 2016 in a monthly partitioned table:

bq rm --table 'mydataset.mytable$201603'

Delete the integer range starting at 20 in an integer range partitionedtable namedmydataset.mytable:

bq rm --table 'mydataset.mytable$20'

API

Call thetables.deletemethod and specify the table and partition decorator using thetableIdparameter.

Partitioned table security

Access control for partitioned tables is the same as access control forstandard tables. For more information, seeIntroduction to table access controls.

Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2026-02-19 UTC.