13.2.2 DELETE 구문
DELETE
테이블의 행을 삭제하는 DML 문입니다.
단일 테이블 구문
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROMtbl_name
[PARTITION (partition_name
...) [WHEREwhere_condition
] [ORDER BY ...] [LIMITrow_count
]
DELETE
문은 tbl_name
행을 삭제하고 삭제 된 행 수를 반환합니다. 삭제 된 행 수를 확인하려면 섹션 12.14 "정보 함수" 에서 설명 된 ROW_COUNT()
함수를 호출합니다.
주요 어구
옵션 WHERE
절의 조건은 어떤 행을 삭제할 것인지 확인합니다. WHERE
절이 없으면 모든 행이 삭제됩니다.
where_condition
은 삭제되는 각 행에 대해 true로 평가되는 식입니다. 이것은 섹션 13.2.9 "SELECT 구문" 에 설명 된대로 지정됩니다.
ORDER BY
절이 지정된 경우, 지정된 순서대로 행이 삭제됩니다. LIMIT
절은 제거 할 행 수에 제한을 설정합니다. 이 어구는 단일 테이블의 삭제에 적용되지만, 복수 테이블의 삭제에 적용되지 않습니다.
여러 테이블 구문
DELETE [LOW_PRIORITY] [QUICK] [IGNORE]tbl_name
[*] [,tbl_name
[*] ... FROMtable_references
[WHEREwhere_condition
]
또는 :
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROMtbl_name
[*] [,tbl_name
[*] ... USINGtable_references
[WHEREwhere_condition
]
권한
테이블에서 행을 삭제하려면 그 테이블에 대한 DELETE
권한이 필요합니다. WHERE
절에 지정되어있는 열 등의 읽을만한 컬럼에 대해서는 SELECT
권한 만 필요합니다.
성능
삭제 된 행 수를 알 필요가없는 경우, 테이블을 비우려면 WHERE
절이없는 DELETE
문보다 TRUNCATE TABLE
문이 더 빠릅니다. DELETE
와 달리 TRUNCATE TABLE
은 트랜잭션 내에서 또는 테이블이 잠겨있는 경우에는 사용할 수 없습니다. 섹션 13.1.33 "TRUNCATE TABLE 구문」 및 섹션 13.3.5 "LOCK TABLES 및 UNLOCK TABLES 구문" 을 참조하십시오.
삭제 작업의 속도 또한 섹션 8.2.2.3 "DELETE 문의 속도" 에 설명 된 요인에 의해 영향을받을 가능성도 있습니다.
특정 DELETE
문에 시간이 느려지지 않도록하기 위해, DELETE
의 MySQL 고유의 LIMIT
절은 삭제되는 행의 최대 수를 지정합니다. 삭제할 행 수가이 제한을 초과하는 경우 영향을받는 행의 수가 row_count
LIMIT
값 이하까지 DELETE
문을 반복합니다.
서브 쿼리
현재 테이블에서 삭제하고 하위 쿼리 같은 테이블에서 선택 할 수 없습니다.
분할 된 테이블
MySQL 5.6.2에서 DELETE
는 삭제 될 행을 선택하려면 하나 이상의 파티션 또는 서브 파티션 (또는 둘 다)의 이름의 쉼표로 구분 된 목록을 포함 PARTITION
옵션을 사용하여 명시 적 파티션 선택을 지원 있습니다. 이 목록에 포함되지 않은 파티션은 무시됩니다. p0
라는 파티션을 포함하는 파티션 된 테이블 t
이 있으면 문 DELETE FROM t PARTITION (p0)
의 실행이 테이블에 대한 ALTER TABLE t TRUNCATE PARTITION (p0)
를 실행하는 것과 같은 효과 수 있습니다. 두 경우 모두 파티션 p0
의 모든 행이 삭제됩니다.
PARTITION
은 WHERE
조건과 함께 사용할 수 있습니다. 그 경우,이 조건 목록되어있는 파티션의 행에 대해서만 테스트됩니다. 예를 들어, DELETE FROM t PARTITION (p0) WHERE c < 5
조건 c < 5
가 true 인 파티션 p0
행만 삭제합니다. 다른 파티션의 행은 체크되지 않기 때문에 DELETE
에 의해 영향을받지 않습니다.
PARTITION
옵션은 또한 여러 테이블의 DELETE
문에서도 사용할 수 있습니다. 이러한 옵션을 FROM
옵션에 지정된 테이블 당 최대 1 개의 사용할 수 있습니다.
자세한 내용 및 예제는 섹션 19.5 "파티션 선택" 을 참조하십시오.
자동 증가 컬럼
AUTO_INCREMENT
컬럼에 최대 값을 갖는 행을 삭제 한 경우, 그 값은 MyISAM
이나 InnoDB
테이블은 재사용되지 않습니다. autocommit
모드에서 DELETE FROM
( tbl_name
WHERE
절은 없음)을 사용하여 테이블의 모든 행을 삭제 한 경우, 그 순서는 InnoDB
와 MyISAM
을 제외한 모든 스토리지 엔진에 시작됩니다. 섹션 14.6.5 "InnoDB에서 AUTO_INCREMENT 처리" 에 설명 된 바와 같이, InnoDB
테이블의 경우이 동작 몇 가지 예외가 있습니다.
MyISAM
테이블의 경우, 멀티 컬럼 키의 AUTO_INCREMENT
보조 컬럼을 지정할 수 있습니다. 이 경우는 순서의 선두에서 제거 된 값의 재사용이 MyISAM
테이블에 대해서도 실행됩니다. 섹션 3.6.9 "AUTO_INCREMENT 사용" 을 참조하십시오.
수식
DELETE
문은 다음 수정 지원합니다.
LOW_PRIORITY
를 지정하면, 서버는 다른 어떤 클라이언트도 테이블에서 읽은 않을 때까지DELETE
의 실행을 지연시킵니다. 이것은 테이블 수준 잠금만을 사용하는 스토리지 엔진 (MyISAM
,MEMORY
및MERGE
)에만 영향을 미칩니다.MyISAM
테이블에서는QUICK
키워드를 사용하면 스토리지 엔진은 삭제 중에 인덱스 리프를 병합하지 않습니다. 이로 인해 일부 유형의 삭제 작업이 가속화 될 가능성이 있습니다.IGNORE
키워드를 지정하면 MySQL 행 삭제 과정에서의 오류를 무시합니다. (분석 단계에서 감지 된 오류는 일반적인 방법으로 처리됩니다.)IGNORE
의 사용을 위해 무시 된 오류는 경고로 반환됩니다.
삭제 순서
DELETE
문에 ORDER BY
절이 포함 된 경우는이 절에서 지정된 순서대로 행이 삭제됩니다. 이것은 주로 LIMIT
와 함께 사용하는 경우에 유효합니다. 예를 들어, 다음 문은 WHERE
절에 일치하는 행을 찾아 그들을 timestamp_column
으로 정렬 한 후 처음 (가장 오래된) 행을 삭제합니다.
DELETE FROM somelog WHERE user = 'jcole' ORDER BY timestamp_column LIMIT 1;
ORDER BY
또한 참조 무결성 위반을 방지하기 위해 필요한 순서로 행을 삭제하는 경우에도 유용합니다.
InnoDB 테이블
큰 테이블에서 많은 행을 삭제하는 경우 InnoDB
테이블에 대한 잠금 테이블의 크기를 초과 할 수 있습니다. 이 문제를 해결하기 위해, 또는 단순히 테이블이 잠긴 채로있는 시간을 최소화하기 위해 DELETE
를 전혀 사용하지 않는 다음의 방법을 사용하는 경우가 있습니다.
삭제되지 않는 행을 선택하여 원래의 테이블과 같은 구조를 가진 빈 테이블에 저장합니다.
INSERT INTO t_copy SELECT * FROM t WHERE ...;
RENAME TABLE
을 사용하여 원래의 테이블을 원자 적으로 이동 한 후 복사본의 이름을 원래 이름으로 변경합니다.RENAME TABLE t TO t_old, t_copy TO t;
원래 테이블을 삭제합니다.
DROP TABLE t_old;
RENAME TABLE
이 실행되는 동안 관련 테이블에는 다른 어떤 세션에서 액세스 할 수 없기 때문에 이름 변경 작업은 동시성의 문제에 제약되지 않습니다. 섹션 13.1.32 "RENAME TABLE 구문" 을 참조하십시오.
MyISAM 테이블
MyISAM
테이블에서 삭제 된 행은 링크 목록에 보관되며 이후 INSERT
작업은 이전 행의 위치를 재사용합니다. 미사용 공간을 확보하고 파일 크기를 줄이려면 OPTIMIZE TABLE
문 또는 myisamchk 유틸리티를 사용하여 테이블을 재구성합니다. OPTIMIZE TABLE
분들이 사용법은 간단하지만, myisamchk가 더 빠릅니다. 섹션 13.7.2.4 "OPTIMIZE TABLE 구문」 및 섹션 4.6.3 "myisamchk - MyISAM 테이블 유지 보수 유틸리티" 를 참조하십시오.
QUICK
규정은 삭제 작업 인덱스 리프가 병합되는지 여부에 영향을 미칩니다. DELETE QUICK
는 삭제 된 행의 인덱스 값이 나중에 삽입 된 행의 비슷한 인덱스 값으로 대체 응용 프로그램에서 특히 유용합니다. 이 경우 삭제 된 값에 의해 남겨진 구멍은 재사용됩니다.
DELETE QUICK
는 삭제 된 값에 의해 새로운 삽입이 다시 발생하는 인덱스 값의 범위 전체에 걸쳐 여유있는 인덱스 블록이 남아있을 경우에는 도움이되지 않습니다. 이 경우 QUICK
을 사용하면 재사용되지 않고 인덱스에서 공간이 낭비 될 가능성이 있습니다. 이러한 시나리오의 예를 보여줍니다.
인덱싱 된
AUTO_INCREMENT
컬럼을 포함하는 테이블을 만듭니다.이 테이블에 여러 행을 삽입합니다. 각 삽입하여 인덱스 앞에 추가되는 인덱스 값이 생성됩니다.
DELETE QUICK
을 사용하여 컬럼의 범위의 마지막에있는 행 블록을 제거합니다.
이 시나리오에서는 삭제 된 인덱스 값과 연관된 인덱스 블록에 여유가 있습니다 만, QUICK
가 사용되고 있기 때문에 다른 인덱스 블록에 병합되지 않습니다. 새로운 삽입이 발생했을 때, 새로운 행은 삭제 된 범위 내의 인덱스 값이 포함되어 있지 않기 때문에 이러한 인덱스 블록은 여유가 남아 있습니다. 또한 삭제 된 일부 인덱스 값이 우연히 여유있는 블록거나 그 옆의 인덱스 블록에 포함되어 있지 않은 한, 나중에 QUICK
없이 DELETE
를 사용하는 경우에도 여유가 남아 합니다. 이러한 상황에서 사용하지 않는 인덱스 공간을 확보하려면 OPTIMIZE TABLE
을 사용합니다.
테이블에서 많은 행을 삭제하려고하는 경우는 DELETE QUICK
계속 OPTIMIZE TABLE
을 사용하는 것이 빠를 수 있습니다. 이렇게하면 인덱스 블록의 다수의 병합 작업이 실행되는 것이 아니라, 인덱스가 다시 작성됩니다.
복수 테이블의 삭제
WHERE
절의 조건에 따라 하나 이상의 테이블에서 행을 삭제하려면 DELETE
문에서 여러 테이블을 지정할 수 있습니다. 여러 테이블의 DELETE
에서는 ORDER BY
또는 LIMIT
를 사용할 수 없습니다. 섹션 13.2.9.2 "JOIN" 에 설명 된 바와 같이, table_references
절은 조인에 포함 된 테이블을 나열합니다.
첫 번째 여러 테이블 구문은 FROM
절 앞에 나열된 테이블의 일치하는 행만 삭제됩니다. 두 번째 여러 테이블 구문에서는 USING
절 앞의 FROM
절에 나열된 테이블의 일치하는 행만 삭제됩니다. 그 효과는 다수의 테이블 행을 동시에 삭제하고 검색에만 사용되는 추가 테이블을 지정할 수 있습니다.
DELETE t1, t2 FROM t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.id = t2.id AND t2.id = t3.id;
또는 :
DELETE FROM t1, t2 USING t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.id = t2.id AND t2.id = t3.id;
이러한 진술은 삭제할 행을 검색 할 때 3 개의 모든 테이블을 사용하지만 테이블 t1
과 t2
일치하는 행만 삭제합니다.
앞의 예에서 INNER JOIN
을 사용하고 있습니다 만, 복수 테이블의 DELETE
문은 SELECT
문에서 허용되는 다른 형태의 결합 ( LEFT JOIN
등)를 사용할 수 있습니다. 예를 들어, t1
에있는 행에서 t2
에 일치하는 것이없는 줄을 삭제하려면 LEFT JOIN
을 사용합니다.
DELETE t1 FROM t1 LEFT JOIN t2 ON t1.id = t2.id WHERE t2.id IS NULL;
이 구문에서는 Access와의 호환성을 위해 각 tbl_name
뒤에 .*
가 허용됩니다.
외부 키 제약이 존재하는 InnoDB
테이블을 포함한 여러 테이블의 DELETE
문을 사용하면 MySQL 최적화가 그 부모의 순서와 다른 순서로 테이블을 처리 할 수 있습니다. 이 경우 문이 실패하고 롤백됩니다. 대신 하나의 테이블에서 삭제 한 뒤, InnoDB
가 제공하는 ON DELETE
기능을 사용하여 다른 테이블이 그에 따라 변경되도록하십시오.
테이블의 별칭을 선언 한 경우, 테이블을 참조 할 때 별칭을 사용해야합니다.
DELETE t1 FROM test AS t1, test2 WHERE ...
여러 테이블의 DELETE
의 테이블 별칭은 그 문 table_references
부분에서만 선언하도록하십시오. 그 이외의 장소에서는 별칭 참조가 허용되지만 별칭 선언은 허용되지 않습니다.
올바른 :
DELETE a1, a2 FROM t1 AS a1 INNER JOIN t2 AS a2 WHERE a1.id = a2.id; DELETE FROM a1, a2 USING t1 AS a1 INNER JOIN t2 AS a2 WHERE a1.id = a2.id;
잘못된 :
DELETE t1 AS a1, t2 AS a2 FROM t1 INNER JOIN t2 WHERE a1.id = a2.id; DELETE FROM t1 AS a1, t2 AS a2 USING t1 INNER JOIN t2 WHERE a1.id = a2.id;