읽 기 | Cloud Spanner | Google Cloud 
 이 페이지 에서 는 읽 기 전용 및 읽 기 - 쓰 기 트랜잭션 의 컨텍스트 외부 에서 Cloud Spanner 의 읽 기 작업 을 수행 하 는 방법 을 설명 합니다 . 따라서 다음 중 하나 에 해당 하 는 경우 트랜잭션 페이지 를 대신 읽 어야 합니다 . 
 하나 이상 의 읽 기 값 에 따라 쓰 기 를 실행 해야 하 는 경우 , 읽 기 - 쓰 기 트랜잭션 의 일부 로 읽 기 를 실행 해야 합니다 . 읽 기 - 쓰 기 트랜잭션 에 대해 자세히 알아보 세요 . 
 일관 된 데이터 보 기 가 필요 한 여러 읽 기 호출 을 수행 하 는 경우 , 읽 기 전용 트랜잭션 의 일부 로 읽 기 를 실행 해야 합니다 . 읽 기 전용 트랜잭션 에 대해 자세히 알아보 세요 . 
 단일 읽 기 호출 을 실행 하 거나 동시 에 데이터 를 읽 어야 하 지만 쓰 지 않 아도 되 는 경우 에 는 이 페이지 를 계속 읽 으세요 . 
 읽 기 유형 
 Cloud Spanner 는 다음 두 가지 읽 기 유형 을 제공 하 므로 데이터 를 읽 을 때 데이터 의 최신 상태 를 결정 할 수 있 습니다 . 
 강력 읽 기 는 현재 타임스탬프 에서 의 읽 기 이 며 이 읽 기 를 시작 할 때 까지 커 밋 한 모든 데이터 를 볼 수 있 습니다 . Cloud Spanner 는 기본 적 으로 강력 읽 기 를 사용 하 여 읽 기 요청 을 처리 합니다 . 
 비활성 읽 기 는 과거 의 타임스탬프 에서 의 읽 기 입니다 . 애플리케이션 이 지연 시간 에 민감 하 지만 비활성 데이터 를 허용 하 는 경우 , 비활성 읽 기 는 성능 상 의 이점 이 있 습니다 . 
 타임스탬프 경계 선택 
 원 하 는 읽 기 유형 을 선택 하 려면 읽 기 요청 에서 타임스탬프 경계 를 설정 합니다 . 타임스탬프 경계 를 선택 할 때 다음 권장 사항 을 따르 세요 . 
 가능 하 다면 강력 읽 기 를 선택 합니다 . 이 유형 은 읽 기 전용 트랜잭션 을 포함 하 는 Cloud Spanner 읽 기 의 기본 타임스탬프 경계 입니다 . 강력 읽 기 에서 는 읽 기 를 수신 하 는 복제 본 에 관계없이 작업 을 시작 하 기 전 에 커 밋 한 모든 트랜잭션 의 영향 을 관찰 할 수 있 습니다 . 이러 한 이유 로 강력 읽 기 를 사용 하 면 애플리케이션 코드 가 보다 간단 해 지 고 애플리케이션 의 신뢰 성 을 높일 수 있 습니다 . TrueTime 및 외부 일관 성 에서 Cloud Spanner 의 일관 성 속성 에 대해 자세히 알아보 세요 . 
 상황 에 따라 지연 시간 때문 에 강력 읽 기 를 실행 할 수 없 다면 비활성 읽 기 ( 제한 된 비활성 또는 완전 비활성 ) 를 사용 하 여 최신 상태 의 읽 기 가 필요 하 지 않 은 경우 에 성능 을 향상 시킵니다 . Cloud Spanner 복제 에 설명 된 대로 우수 한 성능 을 위해 사용 할 수 있 는 적정 한 비활성 값 은 15 초 입니다 . 
 참고 : 비활성 읽 기 는 지역 구성 의 지연 시간 을 단축 하 는 효과 가 없 으므로 인 스턴스 에 멀티 리전 구성 이 없 다면 대부분 의 경우 강력 읽 기 를 사용 해야 합니다 . 
 단일 읽 기 메 서 드 
 Cloud Spanner 는 다음 의 경우 데이터베이스 에서 단일 읽 기 메소드 ( 즉 , 트랜잭션 컨텍스트 외부 에서 읽 기 ) 를 지원 합니다 . 
 SQL 쿼리 문 으로 또는 Cloud Spanner 의 읽 기 API 를 사용 하 여 읽 기 실행 
 테이블 의 단일 행 또는 여러 행 에서 강력 읽 기 수행 
 테이블 의 단일 행 또는 여러 행 에서 비활성 읽 기 수행 
 보조 색인 의 단일 행 또는 여러 행 에서 읽 기 
 아래 섹션 에서 는 Cloud Spanner API 용 Cloud 클라이언트 라이브러리 로 읽 기 메소드 를 사용 하 는 방법 을 설명 합니다 . 
 다음 은 데이터베이스 에 SQL 쿼리 구문 을 실행 하 는 방법 을 보여 줍니다 . 
 ExecuteQuery ( ) 함수 를 사용 하 여 DML 문 을 실행 합니다 . 
 ExecuteReaderAsync ( ) 를 사용 하 여 데이터베이스 를 쿼리 합니다 . 
 Client . Single ( ) . Query 를 사용 하 여 데이터베이스 를 쿼리 합니다 . 
 ReadContext . executeQuery 를 사용 하 여 데이터베이스 를 쿼리 합니다 . 
 Database . run 을 사용 하 여 데이터베이스 를 쿼리 합니다 . 
 Database : : execute 를 사용 하 여 데이터베이스 를 쿼리 합니다 . 
 Database . execute _ sql 을 사용 하 여 데이터베이스 를 쿼리 합니다 . 
 Client # execute 를 사용 하 여 데이터베이스 를 쿼리 합니다 . 
 SQL 문 을 작성 할 때 SQL 쿼리 구문 및 함수 및 연산자 참조 자료 를 찾아보 세요 . 
 강력 읽 기 수행 
 다음 은 데이터베이스 에서 강력 읽 기 로 0 개 이상 의 행 을 읽 는 방법 을 보여 줍니다 . 
 데이터 를 읽 는 코드 는 SQL 쿼리 를 실행 하 여 Cloud Spanner 를 쿼리 하 는 이전 샘플 과 같 습니다 . 
 Client . Single ( ) . Read 를 사용 하 여 데이터베이스 의 행 을 읽 습니다 . 
 이 예시 에서 는 AllKeys 를 사용 하 여 읽 을 키 모음 또는 키 범위 를 정의 합니다 . 
 ReadContext . read 를 사용 하 여 데이터베이스 의 행 을 읽 습니다 . 
 이 예시 에서 는 KeySet 를 사용 하 여 읽 을 키 모음 또는 키 범위 를 정의 합니다 . 
 Table . read 를 사용 하 여 데이터베이스 의 행 을 읽 습니다 . 
 Database : : read 를 사용 하 여 데이터베이스 의 행 을 읽 습니다 . 
 Database . read 를 사용 하 여 데이터베이스 의 행 을 읽 습니다 . 
 Client # read 를 사용 하 여 데이터베이스 의 행 을 읽 습니다 . 
 비활성 읽 기 수행 
 다음 샘플 코드 는 완전 비활성 타임스탬프 경계 를 사용 하 여 데이터베이스 에서 비활성 읽 기 로 0 개 이상 의 행 을 읽 는 방법 을 보여 줍니다 . 제한 된 비활성 타임스탬프 경계 를 사용 하 여 비활성 읽 기 를 수행 하 는 방법 에 대한 자세 한 내용 은 샘플 코드 뒤 에 나오 는 참고 사항 을 참조 하 세요 . 사용 할 수 있 는 타임스탬프 경계 의 여러 유형 에 대한 자세 한 내용 은 타임스탬프 경계 를 참조 하 세요 . 
 MakeReadOnlyTransaction ( ) 및 Transaction : : ReadOnlyOptions ( ) 과 함께 ExecuteQuery ( ) 를 사용 하 여 비활성 읽 기 를 수행 합니다 . 
 std : : cout << " SingerId : " << std : : get < 0 >(* row ) 
 << " AlbumId : " << std : : get < 1 >(* row ) 
 지정 된 TimestampBound . OfExactStaleness ( ) 값 이 있 는 connection 에서 B e g i nReadOnlyTransactionAsync 메 서 드 를 사용 하 여 데이터베이스 를 쿼리 합니다 . 
 참고 : 제한 된 비활성 타임스탬프 경계 를 사용 하 려면 TimestampBound . OfExactStaleness ( ) 값 대신 TimestampBound . OfMaxStaleness ( ) 값 을 정의 합니다 . 
 Client . ReadOnlyTransaction ( ) . WithTimestampBound ( ) 를 사용 하 고 ExactStaleness 값 을 지정 하 여 완전 비활성 타임스탬프 경계 를 통해 데이터베이스 에서 행 읽 기 를 수행 합니다 . 
 참고 : 제한 된 비활성 타임스탬프 경계 를 사용 하 려면 ExactStaleness 값 대신 MaxStaleness 값 을 정의 합니다 . 
 완전 비활성 타임스탬프 경계 를 사용 하 여 데이터베이스 에서 행 읽 기 를 수행 하 려면 지정 된 TimestampBound . ofExactStaleness ( ) 를 포함 하 는 ReadContext 의 read 메 서 드 를 사용 합니다 . 
 참고 : 제한 된 비활성 타임스탬프 경계 를 사용 하 려면 TimestampBound . ofExactStaleness ( ) 대신 TimestampBound . ofMaxStaleness 를 지정 합니다 . 
 완전 비활성 타임스탬프 경계 를 사용 하 여 데이터베이스 에서 행 읽 기 를 수행 하 려면 exactStaleness 옵션 을 포함 하 는 Table . read 를 사용 합니다 . 
 참고 : 제한 된 비활성 타임스탬프 경계 를 사용 하 려면 exactStaleness 옵션 대신 maxStaleness 옵션 을 사용 합니다 . 
 완전 비활성 타임스탬프 경계 를 사용 하 여 데이터베이스 에서 행 읽 기 를 수행 하 려면 지정 된 exactStaleness 값 이 있 는 Database : : read 를 사용 합니다 . 
 완전 비활성 타임스탬프 경계 를 사용 하 여 데이터베이스 에서 행 읽 기 를 수행 하 려면 지정 된 exact _ staleness 값 을 포함 하 는 Database snapshot 의 read 메 서 드 를 사용 합니다 . 
 참고 : 제한 된 비활성 타임스탬프 경계 를 사용 하 려면 exact _ staleness 값 대신 max _ staleness 값 을 정의 합니다 . 
 완전 비활성 타임스탬프 경계 를 사용 하 여 데이터베이스 에서 행 읽 기 를 수행 하 려면 지정 된 staleness 값 ( 초 단위 ) 이 있 는 스냅샷 Client 의 read 메 서 드 를 사용 합니다 . 
 색인 을 사용 하 여 읽 기 수행 
 다음 은 색인 을 사용 하 여 데이터베이스 에서 0 개 이상 의 행 을 읽 는 방법 을 보여 줍니다 . 
 Read ( ) 함수 를 사용 하 여 색인 을 사용 한 읽 기 를 수행 합니다 . 
 색인 을 사용 하 여 데이터 를 읽 으려면 명시 적 으로 색인 을 지정 하 는 쿼리 를 실행 합니다 . 
 색인 을 사용 하 여 데이터베이스 에서 행 을 읽 으려면 Client . Single ( ) . ReadUsingIndex 를 사용 합니다 . 
 색인 을 사용 하 여 데이터베이스 에서 행 을 읽 으려면 ReadContext . readUsingIndex 를 사용 합니다 . 
 색인 을 사용 하 여 데이터베이스 에서 행 을 읽 으려면 Table . read 를 사용 하 여 쿼리 에서 색인 을 지정 합니다 . 
 색인 을 사용 하 여 데이터베이스 에서 행 을 읽 으려면 Database : : read 를 사용 하 여 색인 을 지정 합니다 . 
 색인 을 사용 하 여 데이터베이스 에서 행 을 읽 으려면 Database . read 를 사용 하 여 색인 을 지정 합니다 . 
 색인 을 사용 하 여 데이터베이스 에서 행 을 읽 으려면 Client # read 를 사용 하 여 색인 을 지정 합니다 . 
 동시 에 데이터 읽 기 
 Cloud Spanner 에서 대용량 데이터 를 읽 거나 쿼리 할 때 쿼리 를 작 은 부분 또는 파티션 으로 나누 고 여러 머신 을 사용 하 여 동시 에 파티션 을 가져오 는 방법 이 유용 할 수 있 습니다 . 
 Cloud Spanner 클라이언트 라이브러리 를 사용 하 여 모든 읽 기 API 작업 을 동시 에 수행 할 수 있 습니다 . 단 , 쿼리 실행 계획 의 첫 번 째 연산자 가 분산 통합 인 SQL 쿼리 만 파티션 을 나눌 수 있 습니다 . 특정 SQL 쿼리 의 쿼리 실행 계획 을 보 려면 SQL 권장 사항 의 안내 에 따릅니다 . 
 쿼리 실행 계획 이 표시 되 면 이 계획 의 첫 번 째 연산자 가 분산 통합 인지 확인 합니다 . 
 참고 : 다음 샘플 은 빠른 시작 에 있 는 DDL 테이블 정의 를 사용 합니다 . 
 이 예시 에서 는 Singers 테이블 에서 SQL 쿼리 의 파티션 을 가져오 고 다음 단계 를 통해 각 파티션 에서 쿼리 를 실행 합니다 . 
 Cloud Spanner 일괄 트랜잭션 만들 기 
 파티션 을 여러 작업자 에게 분산 할 수 있 도록 쿼리 의 파티션 생 성 
 각 파티션 의 쿼리 결과 검색 
 참고 : 이 예시 에서 는 편의 상 단일 프로세스 내 의 여러 동시 작업 에서 모든 파티션 을 가져옵니다 . 실제 사용 사례 의 경우 효율 성 을 높이 려면 다른 머신 의 작업자 에게 파티션 을 분산 해야 합니다 . 
 std : : cout << " Number of partitions : " << partitions -> size ( ) << "\ n " 
 Cloud Spanner 클라이언트 및 트랜잭션 만들 기 
 참 고 : 이 예시 에서 는 편의 상 단일 머신 에서 모든 파티션 을 가져오 고 파티션 을 실행 하 여 결과 를 가져옵니다 . 사용 가능 한 프로세서 가 2 개 이상 인 경우 에 동시 에 실행 할 수 도 있 습니다 . 실제 사용 사례 의 경우 효율 성 을 높이 려면 다른 머신 의 작업자 에게 파티션 을 분산 해야 합니다 . 
 Cloud Spanner 일괄 클라이언트 및 트랜잭션 만들 기 
 참 고 : 이 예시 에서 는 편의 상 사용 가능 한 프로세서 가 2 개 이상 인 경우 여러 작업 을 동시 에 실행 하 며 단일 머신 에서 모든 파티션 을 가져옵니다 . 실제 사용 사례 의 경우 효율 성 을 높이 려면 다른 머신 의 작업자 에게 파티션 을 분산 해야 합니다 . 
 txn . partitionQuery ( 
 PartitionOptions . getDefaultInstance ( ) , 
 이 예시 에서 는 Singers 테이블 의 SQL 쿼리 파티션 을 가져온 다음 각 파티션 에서 쿼리 를 실행 하 는 방법 을 보여 줍니다 . 
 참고 : 실제 사용 사례 의 경우 효율 성 을 높이 려면 다른 머신 의 작업자 에게 파티션 을 분산 해야 합니다 . 
 이 코드 부분 은 파티션 을 생성 합니다 . 
 그런 다음 이 코드 부분 은 각 파티션 에서 쿼리 를 실행 합니다 . 
 Cloud Spanner 클라이언트 및 배치 만들 기 
 Cloud Spanner 클라이언트 및 일괄 트랜잭션 만들 기 
 Cloud Spanner 일괄 클라이언트 만들 기 
 파티션 을 여러 작업자 에게 분산 할 수 있 도록 쿼리 의 파티션 만들 기