본문 바로가기
데이터베이스/MySQL 8.4 Docs 번역

[번역] 15.2.13 SELECT Statement

by DevNona 2025. 4. 21.

※ 다소 의역과 주관적 해석이 들어갈 수 있습니다.

SELECT
    [ALL | DISTINCT | DISTINCTROW ]
    [HIGH_PRIORITY]
    [STRAIGHT_JOIN]
    [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
    [SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
    select_expr [, select_expr] ...
    [into_option]
    [FROM table_references
      [PARTITION partition_list]]
    [WHERE where_condition]
    [GROUP BY {col_name | expr | position}, ... [WITH ROLLUP]]
    [HAVING where_condition]
    [WINDOW window_name AS (window_spec)
        [, window_name AS (window_spec)] ...]
    [ORDER BY {col_name | expr | position}
      [ASC | DESC], ... [WITH ROLLUP]]
    [LIMIT {[offset,] row_count | row_count OFFSET offset}]
    [into_option]
    [FOR {UPDATE | SHARE}
        [OF tbl_name [, tbl_name] ...]
        [NOWAIT | SKIP LOCKED]
      | LOCK IN SHARE MODE]
    [into_option]

into_option: {
    INTO OUTFILE 'file_name'
        [CHARACTER SET charset_name]
        export_options
  | INTO DUMPFILE 'file_name'
  | INTO var_name [, var_name] ...
}

export_options:
    [{FIELDS | COLUMNS}
        [TERMINATED BY 'string']
        [[OPTIONALLY] ENCLOSED BY 'char']
        [ESCAPED BY 'char']
    ]
    [LINES
        [STARTING BY 'string']
        [TERMINATED BY 'string']
    ]

SELECT 문은 하나 이상의 테이블에서 레코드들을 검색하는데 사용되며 UNION 연산과 서브쿼리를 포함할 수 있습니다.
INTERSECTEXCEPT 연산도 지원합니다. UNION, INTERSECT 그리고 EXCEPT 연산자는 이 섹션의 뒷부분에서 더 자세히 설명합니다. Section 15.2.15, “Subqueries”도 참고하세요.


SELECT 문은 WITH 절로 시작하여 SELECT 문 내에서 액세스할 수 있는 CTE(공통 테이블 표현식)을 정의할 수 있습니다. Section 15.2.20, “WITH (Common Table Expressions)”을 참고하세요.


가장 일반적으로 사용되는 SELECT 문의 절들은 다음과 같습니다:

  • 각각의 select_expr 는 검색하고 싶은 열(column)을 나타냅니다. 최소 하나의 select_expr 가 있어야합니다.

  • table_references 는 레코드를 검색할 테이블들을 나타냅니다. 이 구문은 Section 15.2.13.2, “JOIN Clause”에서 설명하고 있습니다.

  • SELECT는 table_references 의 테이블 이름 뒤에 파티션 또는 하위 파티션(또는 둘 다) 목록이 있는 PARTITION 절을 사용하여 명시적 파티션 선택을 지원합니다. 이 경우 지정된 파티션에서만 레코드가 선택되고 테이블의 다른 파티션들은 무시됩니다. 더 많은 정보와 예시는 Section 26.5, “Partition Selection”에 있습니다.

  • WHERE 절이 주어지면 레코드가 선택되기 위해 충족해야 하는 조건을 나타냅니다. where_condition 은 선택할 각 레코드에 대해 true로 평가되는 표현식입니다. WHERE 절이 없는 명령문은 모든 행을 선택합니다.

    WHERE 표현식에서 집계(그룹) 함수를 제외한 MySQL에서 지원하는 모든 함수와 연산자를 사용할 수 있습니다. Section 11.5, “Expressions”Chapter 14, Functions and Operators를 참고하세요.


    SELECT 는 어떠한 테이블 참조없이 계산된 행을 검색하는데에도 사용할 수 있습니다.

    예를 들어:

    mysql> SELECT 1 + 1;
                    -> 2

    테이블이 참조되지 않는 상황에서 DUAL을 더미 테이블 이름으로 지정할 수 있습니다.

    mysql> SELECT 1 + 1 FROM DUAL;
                    -> 2

    DUALSELECT 문이 FROM 이나 다른 절을 가져야하는 상황에서 편의상 사용합니다. MySQL은 FROM DUAL을 무시할 것 입니다. 참조되는 테이블이 없다고 MySQL이 FROM DUAL을 요구하지는 않습니다.


    일반적으로 사용되는 절은 위 구문 표현에 표시된 순서대로 정확하게 작성되어야 합니다. 예를 들어, HAVING 절은 무조건 GROUP BY 절 뒤에 와야 하고 ORDER BY 절 앞에 와야 합니다. INTO 절이 존재하는 경우 구문 표현에서 표시된 모든 위치에 나타날 수 있지만 주어진 명령문 내에서는 여러 위치가 아닌 한 번만 나타날 수 있습니다. INTO에 대한 추가 정보는 다음을 참조하세요. Section 15.2.13.1, “SELECT ... INTO Statement”.


    select_expr 항목 리스트는 검색할 컬럼을 나타내는 검색 리스트을 구성합니다. 항목들은 열(column)이나 표현식을 지정하거나 *-shorthand를 사용할 수 있습니다.

  • 수식어 없이 단독으로 사용된 * 검색 리스트는 모든 테이블의 모든 컬럼을 선택하는 축약형으로 사용할 수 있습니다:

    SELECT * FROM t1 INNER JOIN t2 ...
  • tbl_name.* 은 명시한 테이블의 모든 컬럼을 선택하는 수식어 있는 축약형으로 사용할 수 있습니다.

    SELECT t1.*, t2.* FROM t1 INNER JOIN t2 ...
  • 테이블에 보이지 않는 컬럼(invisible 컬럼)이 있는 경우, * 및 tbl_name.* 은 해당 열을 포함하지 않습니다. invisible 컬럼을 포함하려면 명시적으로 참조해야 합니다.
    [ 역주 : invisible 컬럼은 MySQL 8.0.23 버전부터 추가된 기능으로 새 컬럼 추가 시 SELECT *을 사용하는 코드의 영향을 최소화를 위한 호환성 유지와 보안/은닉 목적을 위해 사용됩니다.]

  • select 리스트에 다른 항목과 함께 수식어 없는 *를 사용하면 구문 오류가 발생할 수 있습니다. 예를 들어:

    SELECT id, * FROM t1

    이 문제를 방지하려면 tbl_name.* 처럼 테이블 이름이 포함된 수식어 붙여주세요:

    SELECT id, t1.* FROM t1

    선택 리스에 있는 각각의 테이블에 대해 수식어 있는 tbl_name.* 참조를 사용하세요

    SELECT AVG(score), t1.* FROM t1 ...


다음 항목들은 다른 SELECT 절에 대한 추가적인 정보를 제공합니다:

  • select_expr 에는 *AS alias_name* 을 사용하여 별칭을 지정할 수 있습니다. 별칭은 표현식의 컬럼 이름으로 사용되며 GROUP BY, ORDER BY 또는 HAVING 절에서 사용할 수 있습니다. 예를 들어:

    SELECT CONCAT(last_name,', ',first_name) AS full_name
    FROM mytable ORDER BY full_name;

    식별자로 select_expr 에 별칭을 지정할 때 AS 키워드는 선택 사항입니다. 앞선 예제는 다음과 같이 작성할 수 있습니다:

    SELECT CONCAT(last_name,', ',first_name) full_name
    FROM mytable ORDER BY full_name;

    하지만 AS는 선택 사항이 때문에, 두 select_expr 표현식 사이에 콤마(,)를 잊는다면 미묘한 문제가 발생할 수 있습니다: MySQL은 두 번째를 별칭이라고 해석합니다. 예를 들어, 다음 명령문이 있을 때, columnb는 별칭으로 처리됩니다:

    SELECT columna columnb FROM mytable;

    이러한 이유 때문에 컬럼 별칭을 지정할 때 AS를 사용하는 습관을 들이는 것이 좋습니다.


    WHERE 절에서는 컬럼 별칭을 참조할 수 없습니다. 왜냐하면 WHERE 절이 실행될 시점에는 해당 컬럼의 값이 아직 정해지지 않았을 수 있기 때문입니다. Section B.3.4.4, “Problems with Column Aliases”를 참조하세요.

  • FROM table_references 절은 레코드를 검색할 테이블 또는 테이블들을 나타냅니다. 두 개 이상의 테이블을 지정하면, 이는 조인(join)을 수행하는 것입니다. 조인 구문에 대한 자세한 내용은 Section 15.2.13.2, “JOIN Clause” 을 참조하세요.
    지정된 각 테이블에 대해 선택적으로 별칭을 지정할 수 있습니다.

    tbl_name [[AS] alias] [index_hint]

    인덱스 힌트 사용은 옵티마이저가 쿼리 처리 중에 인덱스를 선택하는 방법에 대한 정보를 얻을 수 있습니다. 이러한 힌트를 지정하기 위한 구문에 대한 설명은 다음을 참조하세요. Section 10.9.4, “Index Hints”


    *SET max_seeks_for_key=value* 를 사용하면 MySQL이 테이블 스캔 대신 키 스캔을 선호하도록 강제하는 대체 방법을 사용할 수 있습니다. Section 7.1.8, “Server System Variables”을 참조하세요.

    [ 역주 : 키 스캔은 인덱스 스캔이라고 이해하시면 됩니다.]

  • 기본 데이터베이스(스키마) 내의 테이블은 tbl_name 으로 참조하거나 db_name.tbl_name 으로 참조해 데이터베이스를 명시적으로 지정할 수 있습니다. 컬럼은 col_name, tbl_name.col_name 또는 db_name.tbl_name.col_name 으로 지정할 수 있습니다. 컬럼 참조가 모호하지 않는 이상 tbl_name 또는 db.name.tbl_name 접두사는 필요하지 않습니다. 더 명시적인 컬럼 참조 형태를 요구하는 모호성 예시를 보시려면 다음을 참조하세요. Section 11.2.2, “Identifier Qualifiers”

  • 테이블 참조는 tbl_name AS alias_name 또는 tbl_name alias_name으로 사용하여 별칭을 지정할 수 있습니다.
    다음 명령어들은 동일합니다.

    SELECT t1.name, t2.salary FROM employee AS t1, info AS t2
    WHERE t1.name = t2.name;
    
    SELECT t1.name, t2.salary FROM employee t1, info t2
    WHERE t1.name = t2.name;
  • 출력을 위해 선택된 컬럼은 ORDER BYGROUP BY 절에서 컬럼 이름, 컬럼 별칭 도는 컬럼 위치를 이용해 참조할 수 있습니다. 컬럼 위치는 1부터 시작하는 정수입니다.

    SELECT college, region, seed FROM tournament
    ORDER BY region, seed;
    
    SELECT college, region AS r, seed AS s FROM tournament
    ORDER BY r, s;
    
    SELECT college, region, seed FROM tournament
    ORDER BY 2, 3;

    역순으로 정렬하려면 ORDER BY 절에 있는 정렬 기준 컬럼의 이름에 DESC 키워드를 추가하세요. 기본은 오름차순입니다; 이것도 ASC 키워드를 사용해 정확히 명시할 수 있습니다.


    괄호로 묶인 서브쿼리 내에 ORDER BY 가 있고 외부 쿼리에서도 ORDER BY 를 사용하는 경우, 그 결과는 정의되지 않으며(즉, MySQL이 보장하지 않음) 향후 MySQL 버전에서 변경될 수 있습니다(미래 MySQL 버전에서 결과가 달라질 수 있음).


    컬럼 위치 사용은 더 이상 권장되지 않습니다. 이는 해당 문법이 SQL 표준에서 제거되었기 때문입니다.

  • SELECT 에서 컬럼 정렬을 위해 ORDER BYGROUP BY 를 사용하는 경우, 서버는 max_sort_length 시스템 변수에 지정된 바이트 수만큼의 초깃값만 사용하여 값을 정렬합니다.
    [ 역주 : 이 설정은 길이가 긴 문자열을 정렬할 때 영향을 줍니다.]

  • MySQL은 GROUP BY 절에서 명시되지 않은 필드도 SELECT 절에서 선택할 수 있도록 허용합니다. 쿼리 결과가 예상과 다를 경우에는 GROUP BY에 대한 설명을 읽어보세요. Section 14.19, “Aggregate Functions”

  • WHERE 절처럼 HAVING 절도 조회 조건을 지정할 수 있습니다. WHERE 절은 컬럼 목록에 대해 조건을 지정할 수 있지만 집계 함수를 참조할 수 없습니다. HAVING 절은 일반적으로 GROUP BY 절로 구성된 그룹에 대한 조건을 지정합니다. 쿼리 결과는 HAVING 조건들을 만족한 그룹만 포함합니다.(GROUP BY가 존재하지 않으면 모든 레코드는 암묵적으로 단일 집계 그룹을 형성합니다.)


    HAVING 절은 거의 마지막에 적용되며, 클라이언트에게 결과를 보내기 직전에 수행됩니다. 최적화는 되지 않습니다.(LIMITHAVING 이후에 적용됩니다.)


    SQL 표준에서는 HAVINGGROUP BY 절에 있는 컬럼이나 집계 함수에 사용되는 컴럼들을 참조해야 한다고 요구합니다. 그러나, MySQL은 이 동작에 대해 확장 기능을 지원하며, HAVING 절에서 SELECT 목록의 컬럼이나 outer 서브쿼리의 컬럼도 참조할 수 있게 허용합니다.


    만약 HAVING 절이 참조하는 컬럼이 모호하다면, 경고가 발생합니다. 다음 명령문에서 col2는 별칭과 컬럼 이름 둘 다로 사용되기 때문에 모호합니다:

    SELECT COUNT(col1) AS col2 FROM t GROUP BY col2 HAVING col2 = 2;

    표준 SQL 동작이 우선시되기에 HAVING 절에서 어떤 컬럼 이름이 GROUP BY 에도 있고 SELECT 에서 별칭으로도 사용되었다면, HAVING 에서는 GROUP BY에 있는 원래 컬럼이 우선 적용됩니다.

  • WHERE 절에 있어야 할 항목에는 HAVING 을 사용하지 마세요. 예를 들어, 다음과 같이 작성하면 안됩니다:

    SELECT col_name FROM tbl_name HAVING col_name > 0;

    대신 이렇게 쓰세요:

    SELECT col_name FROM tbl_name WHERE col_name > 0;
  • HAVING 절은 WHERE 절이 참조할 수 없는 집계 함수를 참조할 수 있습니다:

    SELECT user, MAX(salary) FROM users
        GROUP BY user HAVING MAX(salary) > 10;

    ( 이것은 특정 과거 버전의 MySQL에서 동작하지 않을 수 있습니다.)

  • MySQL은 중복된 컬럼 이름을 허용합니다. 즉, 동일한 이름을 가진 select_expr 이 두 개 이상 있을 수 있을 수 있습니다. 이것은 표준 SQL의 확장입니다. MySQL은 GROUP BYHAVINGselect_expr 값 참조를 허용하기 때문에, 모호함이 발생할 수 있습니다:

    SELECT 12 AS a, a FROM t GROUP BY a;

    위 명령문에서 두 컴럼 모두 a란 이름을 가지고 있습니다. 그룹핑에 정확한 컬럼이 사용을 보장하기 위해, 각 select_expr 에 다른 이름을 사용하세요.

  • WINDOW 절이 있다면 window 함수에서 공유할 수 있는 이름 붙은 윈도우(window)를 정의합니다. 자세한 사항은 다음을 참조하세요 Section 14.20.4, “Named Windows”.

  • MySQL은 ORDER BY 절에서 명확하지 않은 컬럼 이름이나 별칭 참조는 select_expr 값들을 조회한 후 FROM 절에 있는 테이블의 컬럼들을 조회하여 해결합니다. GROUP BY 절과 HAVING 절은 select_expr 값에서 조회하기 전 FROM 절에서 조회합니다. (GROUP BYHAVING의 경우, ORDER BY와 동일한 규칙을 사용했던 MySQL 5.0 이전 동작과 다릅니다.)

  • LIMIT 절은 SELECT 명령문으로 반환되는 레코드 수를 제한하는데 사용할 수 있습니다. LIMIT는 하나 또는 두 개의 숫자 인수를 사용하는데, 둘 다 음이 아닌 정수 상수여야 합니다. 다만 다음과 같은 예외가 있습니다:

    • 준비된 구문(Prepared Statement) 내에서는 LIMIT 매개변수는 ? 플레이스홀더 마커(placeholder marker)를 사용하여 지정할 수 있습니다.

    • 스토어드 프로그램 내에서 LIMIT 파라미터는 정수 값의 루틴 파라미터 또는 로컬 변수로 지정할 수 있습니다.

    두 개의 인수를 사용하는 경우, 첫 번째 인수는 반환할 첫 번째 행의 오프셋을 지정하고 두 번째 인수는 반환할 최대 행의 수를 지정합니다. 첫번째 행의 오프셋은 0입니다.(1이 아님):

    SELECT * FROM tbl LIMIT 5,10;  # Retrieve rows 6-15

    결과 집합의 끝까지 특정 오프셋부터 모든 행을 검색하려면 두 번째 매개변수에 큰 숫자를 사용할 수 있습니다. 다음 문장은 96번 째 행부터 끝까지 모든 행을 검색합니다:

    SELECT * FROM tbl LIMIT 95,18446744073709551615;

    한 개의 인수를 사용하는 경우, 그 값은 결과 집합의 시작부터 리턴하는 레코드 수를 지정합니다.

    SELECT * FROM tbl LIMIT 5;     # Retrieve first 5 rows

    다시 말해서, LIMIT row_countLIMIT 0, row_count 와 동일합니다.


    준비된 문장(prepared statement)에 플레이스홀드를 사용할 수 있습니다. 다음 코드는 tbl 테이블에서 1개의 레코드를 리턴합니다:

    SET @a=1;
    PREPARE STMT FROM 'SELECT * FROM tbl LIMIT ?';
    EXECUTE STMT USING @a;


    다음 코드는 tbl 테이블의 2번째에서 6번째 레코드를 반환합니다.

    SET @skip=1; SET @numrows=5;
    PREPARE STMT FROM 'SELECT * FROM tbl LIMIT ?, ?';
    EXECUTE STMT USING @skip, @numrows;

    PostgreSQL와 호환성을 위해 MySQL은 LIMIT row_count OFFSET offset 구문을 지원합니다.

    괄호로 묶인 쿼리 표현식 내부에서 LIMIT 가 있고 외부 쿼리에도 적용돼 있다면, 결과는 정해지지 않으며 미래의 MySQL 버전에 따라 변할 수 있습니다.

  • SELECT ... INTO 형태의 SELECT 는 쿼리 결과를 파일 또는 스토어드의 변수에 저장할 수 있습니다.

    추가 정보는 Section 15.2.13.1, “SELECT ... INTO Statement”를 참고하세요.

  • 페이지 또는 레코드 락을 사용하는 스토리지 엔진으로 FOR UPDATE 사용 시, 쿼리에서 조사한 레코드는 현재 트랜잭션의 끝까지 write 락이 걸립니다.


    CREATE TABLE new_table SELECT ... FROM old_table ... 같은 SELECT 문장에는 FOR UPDATE 를 사용할 수 없습니다.(만약 시도한다면 쿼리는 Can't update talbe 'old_table' while 'new_table' is being created 이란 에러와 함께 거절됩니다.)


    FOR SHARE 그리고 LOCK IN SHARE MODE 는 다른 트랜잭션이 평가되는 레코드를 읽을 수 있지만 수정하거나 삭제할 수 없는 shared 락을 설정합니다. FOR SHARELOCK IN SHARE MODE 는 동일합니다. 하지만, FOR SHAREFOR UPDATE 와 마찬가지로 NOWAIT, SKIP LOCKD, 그리고 OF tbl_name 옵션을 지원합니다. FOR SHARELOCK IN SHARE MODE 를 대체하지만 LOCK IN SHARE MODE 는 이전 버전과의 호환성을 위해 유지합니다.


    NOWAITFOR UPDATE 또는 FOR SHARE 쿼리를 즉시 실행하며 다른 트랜잭션이 보유한 잠금으로 인해 행 잠금을 얻을 수 없는 경우 오류를 반환합니다.


    SKIP LOCKEDFOR UPDATEFOR SHARE 쿼리를 즉시 실행하며 다른 트랜잭션에 의해 잠금이 걸린 결과 집합의 레코드는 제외합니다.


    NOWAITSKIP LOCKED 옵션은 문장 기반 복제(statement-based replication)에 안전하지 않습니다.

    Note
    잠긴 행을 건너뛰는 쿼리는 일관되지 않은 데이터를 반환합니다. 그러므로 SKIP LOCKED 은 일반적인 트랜잭션 동작에 알맞지 않습니다. 하지만, 다수의 세션이 동일한 큐(queue) 형태의 테이블에 접근할 때, 락 경합을 피하기 위해 사용할 수 있습니다.
    [역주 : SKIP LOCK은 정합성보다 처리 속도가 중요한 작업에 사용할 수 있습니다.]


    OF tbl_name 은 명명된 테이블에 FOR UPDATEFOR SHARE 쿼리를 적용합니다. 예를 들어:

    SELECT * FROM t1, t2 FOR SHARE OF t1 FOR UPDATE OF t2;


    OF tbl_name 이 생략되면 쿼리 블록에서 참조하는 모든 테이블이 잠깁니다. 따라서, 다른 잠금 절과 결합에서 OF tbl_name 없이 잠금 절을 사용하는 것은 에러가 발생합니다. 다수의 잠금 절에서 같은 테이블을 지정하는 것도 에러가 발생합니다. SELECT 문 안에 테이블 이름이 별칭으로 지정되어 있다면, 잠금 절은 별칭만 사용할 수 있습니다. 만약 SELECT 문이 별칭을 명시적으로 지정하지 않았다면, 잠금 절은 실제 테이블 이름만 지정할 수 있습니다.


    FOR UPDATEFOR SHARE 에 대한 추가 정보는 Section 17.7.2.4, “Locking Reads”에 있습니다. NOWAITSKIP LOCKED 옵션에 대한 추가 정보는 Locking Read Concurrency with NOWAIT and SKIP LOCKED에 있습니다.


SELECT 키워드 다음에 쿼리 실행에 영향을 주는 여러 수정자(modifier)들을 사용할 수 있습니다. HIGH_PRIORITY, STRAIGHT_JOIN 그리고 SQL로 시작하는 수정들은 표준 SQL에 대한 MySQL 확장입니다.

  • ALLDISTINCT 수정자는 중복된 레코드가 반환할지 여부를 지정합니다.ALL(디폴트)는 중복을 포함해서 매칭되는 모든 레코드를 반환하도록 지정합니다. DISINCT는 결과 집합에서 중복된 레코드의 제거를 지정합니다. 둘 다 사용하는 것은 에러가 발생합니다. DISTINCROWDISTINCT 와 동의어입니다.


    DISTINCTWITH ROLLUP 을 사용하는 쿼리와 같이 사용할 수 있습니다.

  • HIGH_PRIORITYSELECT 테이블을 수정하는 명령문보다 높은 우선순위를 부여합니다. 매우 빠르고 즉시 완료해야 하는 쿼리에만 사용해야 합니다. 읽기를 위해 테이블에 락이 걸린 동안에 발생한 SELECT HIGH_PRIORITY 쿼리는 테이블이 해제될 때까지 기다리는 업데이트 문이 있는 경우에도 실행됩니다. 이것은 오직 테이블 수준 락을 사용하는 스토리지 엔진에만 영향을 줍니다.(MYISAM, MEMORY 그리고 MERGE 같은)


    HIGH_PRIORITYUNION 의 일부인 SELECT 문과 함께 사용할 수 없습니다.

  • STRAIGHT_JOIN 는 옵티마이저가 FROM 절에 있는 테이블들을 순서대로 조인하는 것을 강제합니다. 이것은 옵티마이저가 테이블을 비효율적인 순서로 조인한다면 쿼리의 속동 향상을 위해 사용할 수 있습니다. STRAIGHT_JOINtable_references 리스트 안에서도 사용할 수 있습니다. Section 15.2.13.2, “JOIN Clause”을 참고하세요.


    STRAIGHT_JOIN 는 옵티마이저가 constsystem 테이블로 다루는 테이블은 적용되지 않습니다.

    [역주 : system 테이블이란 테이블에 딱 한 행만 있는 것을 말함, const 테이블이란 조건에 의해 딱 1개의 레코드만 결과로 나오는 것을 말함]


    이러한 테이블은 하나의 레코드를 생성하고, 쿼리 실행의 최적화 단계에서 읽히고, 쿼리 실행이 진행되기 전에 해당 열에 대한 참조가 적절한 컬럼 값으로 바뀝니다. 이러한 테이블들은 EXPLAIN 으로 출력되는 쿼리 계획에서 먼저 등작합니다. 다음을 참고하세요 Section 10.8.1, “Optimizing Queries with EXPLAIN”. 이러한 예외는 NULL-보완 측(NULL-complemented side)의 외부 조인(즉, LEFT JOIN 의 우측 테이블 또는 RIGHT JOIN 의 좌측 테이블)에 사용되는 constsystem 테이블에는 적용되지 않습니다.

  • SQL_BIG_RESULT 또는 SQL_SMALL_RESULT 는 옵티마이저에게 결과 집합의 레코드 수가 많거나 작은 것을 알려주기 위해 GROUP BY 또는 DISTINCT 와 함께 사용할 수 있습니다. SQL_BIG_RESULT 의 경우 MySQL 은 디스크 기반 임시 테이블이 생성되면 이를 직접 사용하고 GROUP BY 요소에 대한 키가 있는 임시 테이블을 사용하는 것보다 정렬을 선호합니다. SQL_SMALL_RESULT 에 대해서 MySQL은 정렬을 사용하는 것 대신에 인메모리 임시 테이블을 결과 테이블 저장을 위해 사용합니다. 일반적으로 이런 작업은 필요하지 않습니다.

  • SQL_BUFFER_RESULT 는 결과를 임시 테이블에 넣는 것을 강제합니다. 이것은 MySQL 이 테이블 락을 일찍 해제하는데 도움을 주고 결과 집합을 클라이언트에게 보내는데 오래 걸리는 경우에도 도움이 됩니다. 이 수정자는 최상위 SELECT 명령문에만 사용할 수 있고 서브 쿼리나 UNION 다음에 사용할 수 없습니다.

  • SQL_CALC_FOUND_ROWSLIMIT 절과 관계없이 결과 집합에 몇 개의 행 있는지 계산하도록 지시합니다. 그런 다음 행의 수는 SELECT FOUND_ROWS ( )로 검색할 수 있습니다. 다음을 참고하세요 Section 14.15, “Information Functions”.

    Note
    SQL_CALC_FOUND_ROWS 쿼리 수정자와 이에 따른 FOUND_ROWS() 함수는 더 이상 사용되지 않습니다; 추후 MySQL 버전에서 삭제될 것으로 예상됩니다. 대체 방안에 대해 FOUND_ROWS( ) 설명을 읽어보세요.
  • SQL_CACHESQL_NO_CACHE 수정자는 MySQL 8.4 이번의 쿼리 캐시와 같이 쓰였습니다. MySQL 8.4에서 쿼리 캐시는 삭제되었습니다. SQL_CACHE 수정자 또한 삭제되었습니다. SQL_NO_CACHE는 더 이상 사용되지 않고 어떤 기능도 없습니다; 추후 MySQL 릴리스에서 삭제될 것으로 예상됩니다.