Bigtable 테이블의 데이터는 일반적으로 row key로 색인이 생성됩니다.
하지만 소스 테이블에서 연속 구체화된 뷰를 만들어 비동기 보조 색인으로 사용할 수 있습니다. 이렇게 하면 구체화된 뷰를 쿼리하여 다양한 쿼리 조회 패턴을 사용하여 동일한 데이터를 검색할 수 있습니다.
비동기 보조 색인은 소스 테이블의 열 하위 집합과 소스 테이블의 행 키와 다른 행 키를 포함하는 연속 구체화된 뷰입니다.
이러한 행 키는 애플리케이션이 다양한 쿼리 조회 패턴을 기반으로 동일한 데이터를 검색할 수 있도록 하는 다음 변환을 기반으로 할 수 있습니다.
애플리케이션은 다양한 조회 패턴이나 속성을 사용하여 동일한 데이터를 쿼리해야 하는 경우가 많습니다. 예를 들어 이메일 주소나 전화번호로 사용자 정보를 가져오는 애플리케이션을 생각해 보세요. 두 쿼리 패턴에서 동일한 수준의 성능을 원할 수 있습니다. 이메일 주소를 Bigtable 행 키로 만들고 전화번호를 열에 저장하면 전체 테이블 스캔이 필요하므로 전화번호 조회 성능이 느려집니다.
전화번호로 조회할 때 쿼리 성능을 개선하려면 SQL 문으로 연속 구체화된 뷰를 만들면 됩니다. SQL 문은 Bigtable에 다른 행 키로 데이터를 재구성하는 방법을 알려줍니다.
연속 구체화된 뷰는 쿼리할 수 있는 테이블처럼 작동합니다.
그런 다음 뷰를 비동기 보조 색인으로 사용합니다. 이를 통해 애플리케이션이 동일한 데이터에 액세스할 수 있는 또 다른 경로가 제공됩니다. 각 경로에서는 서로 다른 행 키를 사용하므로 각 쿼리에 대해 대체 경로를 선택할 수 있습니다. 쿼리에 가장 적합한 경로를 선택하려면 각 테이블의 행 키 구조와 각 테이블에 저장된 데이터를 이해해야 합니다.
연속 구체화된 뷰를 비동기 보조 색인으로 사용하면 다음 사용 사례에서 쿼리 성능을 개선할 수 있습니다.
데이터 키 재설정: 소스 테이블의 행 키와 다른 키를 사용하여 데이터를 쿼리해야 하는 경우 대체 키를 사용하여 연속 구체화된 뷰를 만든 다음 해당 뷰에 대해 쿼리할 수 있습니다.
데이터 필터링: 소스 테이블을 필터링하고 비동기 보조 색인에 특정 데이터 행만 채우려면 뷰를 정의하는 SQL 쿼리에 WHERE 절을 제공합니다.
속성 키: 열 한정자나 값과 같은 키가 아닌 속성을 기반으로 데이터를 쿼리해야 하는 경우 ORDER BY 절에 포함할 수 있습니다.
비동기 보조 색인 정보
Bigtable에서 연속 구체화된 뷰를 비동기 보조 색인으로 사용하려면 다음 요구사항을 고려하세요.
새 비동기 보조 색인의 행 키에는 소스 테이블의 행 키가 포함되어야 합니다. 그래야 소스 테이블의 행과 연속 구체화된 뷰의 비동기 보조 색인의 행 간에 일대일 매핑이 이루어집니다.
비동기 보조 색인은 소스 테이블과 스키마나 속성이 동일하지 않아도 됩니다. SQL 쿼리의 SELECT 부분에서는 테이블에서 필요한 열과 적용할 데이터의 SQL 변환을 지정해야 합니다.
비동기 보조 색인은 쿼리 패턴에 필요한 데이터만 복사하면 됩니다. 소스 테이블에 모든 소스 데이터를 제공하지 않아도 됩니다.
Bigtable에서 선택한 row key는 기본 정렬 순서를 제공합니다.
비동기 보조 색인을 쿼리하려면 다음 요구사항을 고려하세요.
ORDER BY 절의 모든 열은 SELECT 절에도 포함되어야 합니다.
비동기 보조 색인을 정의하면 애플리케이션에서 소스 테이블을 쿼리할지 비동기 보조 색인을 나타내는 구체화된 뷰를 쿼리할지 선택할 수 있어야 합니다.
애플리케이션은 소스 테이블과 지속적으로 동기화되는 색인에 직접 쓰지 않습니다. 항상 소스 테이블에 쓰기
비동기 보조 색인은 최종 일관성을 갖습니다. 데이터는 먼저 소스 테이블에 작성된 후 비동기 보조 색인 형식으로 변환됩니다.
커버링 인덱스를 만드는 것이 좋습니다. 자세한 내용은 이 문서의 커버링 인덱스 섹션을 참고하세요.
ORDER BY 절에는 소스 테이블의 수정되지 않은 행 키가 포함되어야 하며 모든 데이터는 오름차순으로 정렬되어야 합니다. 소스 테이블의 행 키는 항상 구체화된 뷰에 투영되지만 다른 속성과 결합될 수 있습니다.
ORDER BY 절의 열은 비동기 보조 색인의 구조화된 행 키의 일부가 됩니다. 선택된 다른 모든 열은 비동기 보조 색인의 비키 열 값이 됩니다. ORDER BY 절의 값을 특정 Bigtable용 GoogleSQL 데이터 유형으로 변환하면 비동기 보조 색인의 구조화된 행 키에 데이터 유형이 유지됩니다.
커버링 색인
커버링 인덱스에는 쿼리에 필요한 모든 열이 포함됩니다. 커버링 색인을 쿼리하면 Bigtable은 소스 테이블에 액세스하지 않고도 색인에서 필요한 모든 데이터를 직접 가져올 수 있습니다. 이 방법은 디스크 읽기 수를 최소화하므로 최적의 성능을 위해 권장됩니다. 커버링 인덱스를 만들려면 SELECT 문이 쿼리에 필요한 모든 열을 지정해야 합니다.
커버링되지 않은 색인을 만들려면 색인을 쿼리한 다음 결과를 사용하여 소스 테이블에서 필요한 추가 열을 조회합니다.
비동기 보조 색인 정의
비동기 보조 색인은 비동기 보조 색인을 정의하는 SQL 쿼리를 사용하여 연속 구체화된 뷰를 만들어 만듭니다.
다음 예에서 SQL 쿼리는 사용자 상호작용 데이터를 쿼리할 수 있는 비동기 보조 색인을 만듭니다. ORDER BY 절에서는 사용자의 전화번호, 사용자 ID, 이메일 주소를 조합하여 비동기 보조 색인의 구조화된 행 키를 정의합니다. 또한 activity column family에 interactions라는 이름을 할당합니다.
[[["이해하기 쉬움","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(UTC)"],[],[],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)"]]