MySQL 인덱스 퀴즈 - 세트 H
총 7개 문제로 구성된 MySQL 인덱스 학습 퀴즈입니다.
문제 1. 기본키를 AUTO_INCREMENT, UUID로 하는 각각 두 가지 테이블이 있다
```sql
CREATE TABLE ai_table (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
payload CHAR(100) NOT NULL
) ENGINE=InnoDB;
CREATE TABLE uuid_table (
id BINARY(16) PRIMARY KEY,
payload CHAR(100) NOT NULL
) ENGINE=InnoDB;
```
Page Split을 고려하여 10만건의 대량 데이터를 삽입할 때의 두 테이블의 실행 속도를 비교하시오
- AUTO_INCREMENT를 기본키로 하는 테이블의 데이터 삽입속도가 더욱 빠르다
- UUID를 기본키로 하는 테이블의 데이터 삽입 속도가 더욱 빠르다
- 두 테이블 간 삽입 속도에 큰 차이가 없다.
문제 2. 기본키를 AUTO_INCREMENT, UUID로 하는 각각 두 가지 테이블이 있다
```sql
CREATE TABLE t_ai (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
num INT NOT NULL,
payload CHAR(100) NOT NULL
) ENGINE=InnoDB;
CREATE TABLE t_uuid (
id BINARY(16) PRIMARY KEY,
num INT NOT NULL,
payload CHAR(100) NOT NULL
) ENGINE=InnoDB;
```
각 테이블에 1000만건의 데이터를 삽입했다. 이때 num은 rowID와 같이 1부터 순차적으로 증가한다.
가령 테이블에 다음과 같이 저장되어 있다
```text
//ai_table
+---------------------+------+-----------+
|id(AUTO_INCREMENT) |num |payload |
+---------------------+------+-----------+
|1 |1 |payload1 |
|2 |2 |payload2 |
|3 |3 |payload3 |
+---------------------+------+-----------+
//uuid_table
+-----------------------------------------+------+-----------+
|id(UUID) |num |payload |
+-----------------------------------------+------+-----------+
|2e8ac55d-e91f-11f0-a300-0242ac110002 |1 |payload1 |
|2e8ad1eb-e91f-11f0-a300-0242ac110002 |2 |payload2 |
|2e8ae07e-e91f-11f0-a300-0242ac110002 |3 |payload3 |
+-----------------------------------------+------+-----------+
```
이때 다음 삭제 쿼리를 실행시켰다.
```sql
DELETE FROM {테이블 명} WHERE num < 500000;
```
해당 쿼리는 PK와 num의 범위 순차성이 보장된 t_ai의 경우 데이터를 페이지 순차적으로 삭제하는 쿼리가 되고, 실제 데이터를 정렬하는 PK와 num의 정렬이 일치하지 않는 t_uuid에게는 데이터 랜덤 삭제를 시도하는 쿼리가 된다.
이때 두 테이블의 Index Page Merge의 횟수를 비교하시오
- AUTO_INCREMENT 기본키로 하는 테이블의 인덱스 페이지 머지 시도 횟수가 더 많다.
- UUID를 기본키로 하는 테이블의 인덱스 페이지 머지 시도 횟수가 더 많다.
문제 3. 다음 함수 기반 인덱스가 선언된 테이블이 있다.
```sql
CREATE TABLE human (
user_id BIGINT PRIMARY KEY,
first_name VARCHAR(10),
last_name VARCHAR(10),
INDEX ix_fullname ((CONCAT(first_name, '', last_name))) #함수 기반 인덱스
);
```
각 쿼리의 ix_fullname 인덱스 활용여부를 고르시오.
```text
1번 쿼리 : SELECT * FROM human WHERE CONCAT(first_name, '', last_name) = 'johnsmith';
2번 쿼리 : EXPLAIN SELECT * FROM human WHERE first_name = 'john' AND last_name = 'smith';
```
- 1번 쿼리 : O | 2번 쿼리: O
- 1번 쿼리 : X | 2번 쿼리: O
- 1번 쿼리 : O | 2번 쿼리: X
- 1번 쿼리 : X | 2번 쿼리: X
문제 4. 다음 함수 기반 인덱스가 선언된 테이블이 있다.
```sql
CREATE TABLE human (
user_id BIGINT PRIMARY KEY,
first_name VARCHAR(10),
last_name VARCHAR(10),
INDEX ix_fullname ((CONCAT(first_name, '', last_name))) #함수 기반 인덱스
);
```
각 쿼리의 ix_fullname 인덱스 활용여부를 고르시오.
```text
1번 쿼리 : SELECT * FROM human WHERE CONCAT(first_name, ' ', last_name) = 'john smith';
2번 쿼리 : SELECT * FROM human WHERE CONCAT(first_name, '', last_name) LIKE 'john%';
```
- 1번 쿼리 : O | 2번 쿼리: O
- 1번 쿼리 : X | 2번 쿼리: O
- 1번 쿼리 : O | 2번 쿼리: X
- 1번 쿼리 : X | 2번 쿼리: X
문제 5. 다음 테이블이 있다.
```sql
CREATE TABLE products (
product_id INT PRIMARY KEY,
category_code CHAR(3) NOT NULL,
product_name CHAR(5) NOT NULL,
description TEXT
);
```
원하는 데이터 행을 category_code를 통해서도 찾을 수도 있고, product_name을 통해서도 찾을 수도 있다. 어떤 컬럼으로 인덱스를 만드는 것이 I/O 바운드 작업을 덜 할 수 있는가?
- category_code
- product_name
문제 6. 다음 테이블이 있다.
```sql
CREATE TABLE employees (
emp_no INT NOT NULL,
birth_date DATE NOT NULL,
first_name VARCHAR(14) NOT NULL,
last_name VARCHAR(16) NOT NULL,
gender ENUM('M', 'F') NOT NULL,
hire_date DATE NOT NULL,
PRIMARY KEY (emp_no),
INDEX idx_first_name (first_name),
);
```
다음 쿼리에서 옵티마이저가 인덱스를 활용하는 방법을 예측하시오
```sql
SELECT * FROM employees WHERE first_name='Georgi' AND emp_no BETWEEN 10000 AND 20000;
```
해당 쿼리의 결과값은 10건 정도가 전부이지만, 두 조건 각각에 대해서는 상당한 행이 필터링된다.
- 테이블 풀스캔을 통해 조건에 만족하는 행을 하나씩 검토한다
- idx_first_name 만 동등조건에 활용하고 emp_no 클러스터링 인덱스는 활용하지 않는다
- emp_no 클러스터링 인덱스만 동등조건에 활용하고 idx_first_name는 활용하지 않는다
- 각각 인덱스를 활용해 조건에 맞는 행을 골라낸 후, 교집합으로 머지하여 결과를 반환한다.
문제 7. 다음 테이블이 있다.
```sql
CREATE TABLE index_test (
id INT PRIMARY KEY AUTO_INCREMENT,
col1 INT,
col2 INT,
col3 VARCHAR(100)
);
CREATE INDEX idx_col1 ON index_test(col1);
CREATE INDEX idx_col2 ON index_test(col2);
```
다음 쿼리에서 옵티마이저가 인덱스를 활용하는 방법을 예측하시오
```sql
SELECT * FROM index_test WHERE col1 = 1 OR col2 = 2;
```
두 조건 각각에 대해 상당한 행이 필터링된다. (col1 = 1인 행은 500개, col2 = 2인 행은 300개이며, 전체 테이블은 100만 건이다)
- 테이블 풀스캔을 통해 조건에 만족하는 행을 하나씩 검토한다
- idx_col1 만 동등조건에 활용하고 idx_col2는 활용하지 않는다
- idx_col2만 동등조건에 활용하고 idx_col1는 활용하지 않는다
- 각각 인덱스를 활용해 조건에 맞는 행을 골라낸 후, 합집합으로 머지하여 결과를 반환한다.
다른 퀴즈 세트 보기