사전 질의
개념

질의

gabury1고친 사람 github-actions[bot]

질의는 데이터를 가진 시스템에 원하는 것을 묻는 요청입니다. 묻는 쪽은 무엇을 원하는지만 적습니다. 찾는 방법은 답하는 쪽이 정합니다. 데이터베이스에서 가장 자주 쓰는 말입니다. 이름을 주소로 바꾸는 시스템이나 검색 엔진에서도 같은 뜻으로 씁니다.

쉽고 빠른 이해

질의는 데이터를 가진 쪽에 「이런 조건에 맞는 것을 주세요」라고 묻는 일입니다. 「7번 사용자의 주문을 전부 주세요」가 질의 하나입니다.

이게 없으면 데이터를 쓰는 프로그램마다 파일을 직접 열고 한 줄씩 뒤져야 합니다. 저장 방식이 바뀌면 그 코드를 전부 고쳐야 합니다. 질의로 물으면 찾는 일은 데이터를 가진 쪽이 맡습니다.

어떻게 도나:

  1. 조건을 담아 묻습니다
  2. 받은 쪽이 어떻게 찾을지 스스로 정합니다
  3. 조건에 맞는 결과를 돌려줍니다

대가도 있습니다. 찾는 방법은 남에게 맡겼습니다. 그래서 한 줄짜리 질의가 뒤에서 데이터 전체를 훑어도 겉으로는 안 보입니다. 질의가 몰리면 묻는 프로그램보다 답하는 서버가 지칩니다.

질의는 읽기만 합니다. 데이터를 바꿀 때는 질의가 아니라 갱신을 보냅니다.

상세

도서관 사서에게 「이 작가 책 있나요」라고 묻는 장면을 떠올려 봅시다. 묻는 사람은 책이 몇 번 서가에 꽂혔는지 모릅니다. 사서가 목록을 보고 찾아서 건네줍니다.

질의(query)는 데이터를 가진 시스템에 조건을 담아 보내는 물음입니다. 받은 시스템은 조건에 맞는 결과를 돌려줍니다. 예를 들어 주문 기록에 「어제 들어온 주문 중 금액이 만 원 넘는 것」을 묻는 것이 질의 하나입니다. 시스템은 뜻이 모호해도 되묻지 않습니다. 그래서 물음은 정해진 문법으로 적습니다.

질의가 필요한 까닭은 찾는 일과 쓰는 일을 떼어 놓기 위해서입니다. 프로그램이 데이터의 저장 모양을 직접 뒤지면, 저장 모양이 바뀔 때 프로그램도 같이 고쳐야 합니다. 질의로 물으면 프로그램은 물음만 알면 됩니다. 저장 모양은 답하는 쪽 안에 숨습니다.

실무에서는 영어를 그대로 읽어 「쿼리」라고도 부릅니다. 둘은 같은 말입니다.

질의를 쓰는 분야

질의라는 말은 한 분야에 묶여 있지 않습니다. 데이터를 가진 쪽과 묻는 쪽이 나뉘는 곳이면 어디서나 씁니다. 분야마다 묻는 것과 돌아오는 것이 다를 뿐 뼈대는 같습니다.

분야 묻는 것 돌아오는 것
관계형 데이터베이스 테이블과 조건 조건에 맞는 행
DNS(Domain Name System, 도메인 네임 시스템) 도메인 이름 그 이름에 붙은 주소 같은 값
검색 엔진 찾을 낱말 관련 높은 순으로 줄 세운 문서
시계열 데이터베이스 지표 이름과 시간 범위 시간별 값
GraphQL 받고 싶은 필드 그 필드만 담은 응답

이 편은 이 가운데 둘을 자세히 봅니다. 데이터베이스의 질의와 DNS 의 질의입니다. 둘 다 서버가 질의를 얼마나 많이, 얼마나 빨리 받아 내는지가 운영 문제로 이어집니다.

데이터베이스의 질의

데이터베이스에서 질의는 대개 SQL(Structured Query Language, 구조화 질의 언어)로 씁니다. SQL 은 테이블에 담긴 데이터를 묻고 고치는 언어입니다. 읽는 질의는 SELECT 로 시작합니다.

아래 테이블 orders 에 주문 세 건이 있다고 해 봅시다.

id user_id total
1 7 12000
2 3 5000
3 7 8000

7번 사용자에 대해 두 가지를 물어 봅니다. 주문이 몇 건인지와 합계가 얼마인지입니다. 오른쪽 주석이 돌아오는 값입니다.

SQL
SELECT count(*) FROM orders
 WHERE user_id = 7;       -- 2
SELECT sum(total) FROM orders
 WHERE user_id = 7;       -- 20000

두 질의 어디에도 「1번 행부터 읽어라」 같은 절차가 없습니다. 원하는 결과의 조건만 적었습니다. 이렇게 무엇을 원하는지만 적는 방식을 선언형이라고 부릅니다.

「질의」는 넓게도 좁게도 쓰입니다. 좁게는 데이터를 읽기만 하는 SELECT 를 가리킵니다. 넓게는 데이터를 바꾸는 INSERT · UPDATE · DELETE 까지 데이터베이스에 보내는 문장 전부를 질의라고 부릅니다. 「쿼리가 오래 걸린다」고 할 때는 대개 넓은 뜻입니다.

질의가 처리되는 순서

선언형으로 물었으니 찾는 절차는 데이터베이스가 정해야 합니다. 이 소절은 질의 하나가 들어와 결과가 나갈 때까지 거치는 단계를 봅니다.

flowchart TD
    A["질의 문장이 들어온다"] --> B["문법을 읽어 구조로 바꾼다"]
    B --> C["찾는 방법 후보를 비교해 하나를 고른다"]
    C --> D["고른 방법대로 데이터를 읽는다"]
    D --> E["결과를 돌려준다"]

둘째 단계에서 데이터베이스는 문장을 읽고, 어느 테이블에서 어떤 조건으로 찾는지 알아볼 수 있는 구조로 바꿉니다. 문법이 틀린 질의는 여기서 거절됩니다.

셋째 단계가 핵심입니다. 같은 결과를 내는 방법은 여럿입니다. 테이블 전체를 처음부터 끝까지 훑을 수 있습니다. 인덱스로 해당 행만 골라 읽을 수도 있습니다. 인덱스는 책 뒤의 찾아보기처럼 값에서 행의 위치로 바로 가게 해 주는 보조 구조입니다.

방법을 고르는 부품을 질의 옵티마이저라고 부릅니다. 앞의 orders 질의라면 user_id 인덱스를 쓸지, 테이블 전체를 훑을지를 옵티마이저가 고릅니다.

옵티마이저가 고른 절차 한 벌이 실행 계획입니다. 같은 질의도 데이터 양이나 인덱스 유무에 따라 실행 계획이 달라집니다.

선언형의 대가가 여기서 드러납니다. 질의 문장만 보고는 무슨 절차로 도는지 알 수 없습니다. 짧은 질의가 오래 걸린다면 실행 계획을 열어 전체를 훑고 있는지부터 봅니다.

질의가 몰릴 때

질의 하나하나는 서버의 연산 능력과 디스크 읽기를 씁니다. 동시에 들어오는 질의가 늘면 서버 한 대가 감당하는 양을 넘습니다. 이때 데이터를 여러 서버로 나누는 방법이 샤딩입니다. 예를 들어 orders 를 사용자 번호로 나누면, 7번 사용자의 주문은 서버 한 대에만 모입니다.

데이터를 나눈 뒤에는 질의가 어느 서버로 가는지가 성능을 가릅니다. 조건에 나누는 기준 값(여기서는 사용자 번호)이 들어 있으면 질의를 서버 한 대로만 보낼 수 있습니다. 조건에 그 값이 없으면 모든 서버에 질의를 보내고 결과를 모아야 합니다.

앞의 것은 서버를 늘릴수록 부담이 흩어집니다. 뒤의 것은 모든 서버에 물어야 합니다. 그래서 서버가 늘수록 질의 하나에 드는 일도 늡니다.

DNS 의 질의

DNS 는 example.com 같은 이름을 컴퓨터가 쓰는 주소로 바꿔 주는 시스템입니다. 여기서 질의는 「이 이름의 주소가 뭔가요」라고 묻는 메시지 한 통입니다. 답하는 쪽은 응답 메시지 한 통을 돌려줍니다.

질의에는 이름과 함께 원하는 값의 종류를 적습니다. 이 종류를 레코드 타입이라고 부릅니다. IP(Internet Protocol, 인터넷 프로토콜) 버전 4 주소를 원하면 A 레코드를 묻습니다.

웹 페이지 하나를 열 때도 이름 조회가 여러 번 일어납니다. 그래서 DNS 서버는 초마다 매우 많은 질의를 받습니다.

질의와 갱신

질의는 원칙적으로 데이터를 읽기만 하고 바꾸지 않습니다. 데이터를 바꾸는 요청은 따로 갱신이라고 부릅니다. 둘을 나누면 질의는 몇 번을 다시 보내도 데이터가 그대로라서 안심하고 재시도할 수 있습니다.

이 구분을 언어에 박아 둔 곳도 있습니다. GraphQL 은 읽기 요청을 질의(query), 쓰기 요청을 변형(mutation)으로 나눕니다.

설계 수준에서 나누기도 합니다. 읽기용으로 따로 둔 데이터 모양을 읽기 모델, 쓰기용 데이터 모양을 쓰기 모델이라고 합니다. 읽기와 쓰기가 원하는 모양이 다를 때 둘을 따로 두는 설계가 CQRS(Command Query Responsibility Segregation, 명령 질의 책임 분리)입니다.

「데이터베이스의 질의」에서 본 넓은 뜻과 헷갈리지 않게 정리합니다. 뜻을 가르는 것은 낱말이 아니라 맥락입니다. 같은 낱말이 SQL 문장 전체를 말할 때는 쓰기까지 넓게 쓰입니다. 갱신과 맞세울 때는 읽기만 좁게 쓰입니다.

관련 항목

질의를 받아 답하는 시스템

데이터베이스 · 관계형 데이터베이스 · 시계열 데이터베이스 · 검색 엔진 · DNS · DNS 리졸버 · 네임서버

질의를 적는 언어

SQL · GraphQL · PromQL · 데이터 서브언어 · 선언형 프로그래밍

질의를 이루는 SQL 구성 요소

SELECT · WHERE · 조인 · 집계 함수 · 뷰 · 서브쿼리

데이터베이스가 질의를 처리하는 단계

질의 옵티마이저 · 질의 계획기 · 실행 계획 · 인덱스 · 순차 스캔 · 인덱스 스캔 · 통계

질의 부하를 나누는 수단

샤딩 · 복제 · 읽기 복제본 · 질의 라우터 · 캐싱 · 로드 밸런서

질의에서 자주 나는 문제

느린 쿼리 · N+1 문제 · SQL 인젝션 · 전체 테이블 스캔

질의와 맞세워지는 대립 개념

갱신 · 변형 · CQRS · 명령-질의 분리 · 멱등성

DNS 질의에 쓰이는 개념

DNS 레코드 · A 레코드 · IP 주소 · 도메인 이름 · 재귀 질의

다른 이름: 쿼리 · query · Query