[[["容易理解","easyToUnderstand","thumb-up"],["確實解決了我的問題","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["難以理解","hardToUnderstand","thumb-down"],["資訊或程式碼範例有誤","incorrectInformationOrSampleCode","thumb-down"],["缺少我需要的資訊/範例","missingTheInformationSamplesINeed","thumb-down"],["翻譯問題","translationIssue","thumb-down"],["其他","otherDown","thumb-down"]],["上次更新時間:2025-09-04 (世界標準時間)。"],[],[],null,["# Create an asynchronous secondary index\n======================================\n\n|\n| **Preview**\n|\n|\n| This product or feature is subject to the \"Pre-GA Offerings Terms\" in the General Service Terms section\n| of the [Service Specific Terms](/terms/service-terms#1).\n|\n| Pre-GA products and features are available \"as is\" and might have limited support.\n|\n| For more information, see the\n| [launch stage descriptions](/products#product-launch-stages).\n\nYou can use continuous materialized views as asynchronous secondary indexes for\ntables.\n\nBefore you read this page, familiarize yourself with\n[Continuous materialized views](/bigtable/docs/continuous-materialized-views).\n\nData in a Bigtable table is typically indexed by\n[row keys](/bigtable/docs/schema-design#row-keys).\nHowever, you can create a continuous materialized view from a source table and\nuse it as an asynchronous secondary index. This lets you retrieve the same data using\ndifferent query lookup patterns by querying the materialized view.\n\nAn *asynchronous secondary index* is a continuous materialized view that contains a\nsubset of columns from a source table, along with a row key that is different from the row key in the source table.\nThese row keys might be based on the following transformations that allow your\napplication to retrieve the same data based on different query lookup patterns:\n\n- Attributes within the source table, such as column qualifiers, column values, or parts of the source row key.\n- A reformatting of the row key.\n- A transformation that combines the row key with an attribute.\n\nBigtable synchronizes asynchronous secondary indexes with the source\ntable automatically in a way that is [eventually consistent](/bigtable/docs/replication-overview#consistency-model).\n\nWhen to use an asynchronous secondary index\n-------------------------------------------\n\nApplications often need to query the same data using different lookup patterns\nor attributes. For example, consider an application that retrieves user\ninformation by either the email address or a phone number. You might want the\nsame level of performance across both query patterns. If you make the email\naddress your Bigtable row key and store telephone numbers in a\ncolumn, then the performance of the phone number lookup is slower because\nit requires a full table scan.\n\nTo improve query performance when looking up by a telephone number, you can\ncreate a continuous materialized view with a SQL statement. The SQL statement\ninstructs Bigtable how to restructure your data with a different row key.\nA continuous materialized view acts like a table that you can query.\nThen you use the view as an asynchronous secondary index. It gives your application\nanother access path to the same data. Each path uses a different\nrow key so you can choose an alternative path for each query. To choose the\nbest path for your query, understand the structure of the row key for each table\nand the data that each table stores.\n\nUsing a continuous materialized view as an asynchronous secondary index\ncan improve query performance in the following use cases:\n\n- **Rekeying your data**: If you need to query your data by using a different key than the source table's row keys, you can then create a continuous materialized view with the alternative key and query against that view.\n- **Filtering data** : If you want to filter the source table and populate only specific rows of data in the asynchronous secondary index, then provide a `WHERE` clause in the SQL query that defines the view.\n- **Attribute keys** : If you need to query your data based on a non-key attribute, such as a column qualifier or value, you can include it in your `ORDER BY` clause.\n\nAbout asynchronous secondary indexes\n------------------------------------\n\nTo use a continuous materialized view in Bigtable as an asynchronous\nsecondary index, consider the following requirements:\n\n- The row key for a new asynchronous secondary index must include the row key of the source table to help ensure a one-to-one mapping between rows in the source table and rows in the asynchronous secondary index of the continuous materialized view.\n- The asynchronous secondary index doesn't have to have the same schema or attributes as the source table. In the `SELECT` part of the SQL query, you must specify which columns from the table are necessary and any SQL transformations of the data that you want to apply.\n- The asynchronous secondary index only needs to copy data that you need for the query pattern. Providing all the source data in the source table is not required.\n- In Bigtable, the row key that you choose provides the default sort order.\n\nTo query asynchronous secondary indexes, consider the\nfollowing requirements:\n\n- Every column in the `ORDER BY` clause must also be included in the `SELECT` clause.\n- Once you define the asynchronous secondary index, your application must be able to choose between querying the source table or the materialized view that represents the asynchronous secondary index.\n- Applications don't write directly to the index, which continuously synchronizes with the source table. Always write to the source table.\n- The asynchronous secondary index is eventually consistent; data is written to the source table first and then transformed to the asynchronous secondary index format.\n- We recommend that you create a covering index. For more information, see the [Covering indexes](#covering-indexes) section of this document.\n- The `ORDER BY` clause must contain the unmodified row key of the source table, and all data must be sorted in an ascending order. The row key in the source table is always projected to the materialized view; however, it can be combined with other attributes.\n- The columns in the `ORDER BY` clause become part of the [structured row key](/bigtable/docs/manage-row-key-schemas) of the asynchronous secondary index. All other selected columns become non-key column values in the asynchronous secondary index. If you convert a value in the `ORDER BY` clause to a specific [GoogleSQL for\n Bigtable](/bigtable/docs/googlesql-overview) data type, it retains its data type in the structured row key of the asynchronous secondary index.\n\nCovering indexes\n----------------\n\nA *covering index* includes all the columns that your queries need. When you\nquery a covering index, Bigtable can retrieve all the required\ndata directly from the index, without having to access the source table. We\nrecommend this approach for optimal performance because it minimizes the number\nof disk reads. To create a covering index, make sure that your `SELECT`\nstatement specifies all the columns that you need in your queries.\n\nWhen you want to create a non-covering index, query the index and then use the\nresults to look up the additional columns that you need from the source table.\n\nDefine an asynchronous secondary index\n--------------------------------------\n\nYou create an asynchronous secondary index by\n[creating a continuous materialized view](/bigtable/docs/manage-continuous-materialized-views)\nwith a SQL query that defines the asynchronous secondary index.\n\nIn the following example, the SQL query creates an asynchronous secondary index that\nlets you query user interactions data. The `ORDER BY` clause defines the\nstructured row key of the asynchronous secondary index, using a combination of the user's phone\nnumber, user ID, and email address. It also assigns the name `interactions` to\nthe `activity` column family: \n\n SELECT\n user['phone'] AS phone,\n CAST(user['id'] AS INT64) AS user_id,\n _key AS email,\n activity AS interactions\n FROM CLICKS_TABLE\n ORDER BY 1, 2, 3;\n\nThe following table explains how the index is created by comparing the view of the same row in the source table with the corresponding asynchronous secondary index:\n\nLimitations\n-----------\n\n- To read the output key, which is the asynchronous secondary index key, you can only use SQL queries.\n\nWhat's next\n-----------\n\n- [Continuous materialized view queries](/bigtable/docs/continuous-materialized-view-queries)\n- [Create and manage continuous materialized views](/bigtable/docs/manage-continuous-materialized-views)\n- [Schema design best practices](/bigtable/docs/schema-design)\n- [Manage row key schemas](/bigtable/docs/manage-row-key-schemas)\n- [Distributed counting in Bigtable](https://cloud.google.com/blog/products/databases/distributed-counting-with-bigtable)"]]