2. Internal temporary table
•FROM 절의 서브 쿼리 -> 임시 테이블(Derived)
SELECT * FROM (
SELECT * FROM (
SELECT * FROM tab WHERE fd IN (1)
) x
) y;
+----+-------------+------------+
| id | select_type | table
|
+----+-------------+------------+
| 1 | PRIMARY
| <derived2> |
| 2 | DERIVED
| <derived3> |
| 3 | DERIVED
| tab
|
+----+-------------+------------+
Real MySQL
http://cafe.naver.com/realmysql
3. Internal temporary table
•사용된 임시 테이블 개수
mysql> SHOW STATUS LIKE 'Created_tmp_tables‘;
+-------------------------+-------+
| Created_tmp_tables
| 13
|
+-------------------------+-------+
mysql> SELECT * FROM (
SELECT * FROM (
SELECT * FROM tab where fd in (1)) x) y;
…
mysql> SHOW STATUS LIKE 'Created_tmp_tables‘;
+-------------------------+-------+
| Created_tmp_tables
| 15
|
+-------------------------+-------+
Real MySQL
http://cafe.naver.com/realmysql
4. Deterministic
• CREATE FUNCTION
CREATE
FUNCTION getCurrentTime() RETURN DATETIME
[ DETERMINISTIC | NOT DETERMINISTIC ]
BEGIN
DECLARE v_now DATETIME;
SELECT NOW() INTO v_now;
RETURN v_now;
END
Real MySQL
http://cafe.naver.com/realmysql
5. Deterministic
• 두 쿼리의 차이는 ?
SELECT *
FROM huge_table
WHERE expire_dttm > getCurrTime_DETERM ();
SELECT *
FROM huge_table
WHERE expire_dttm > getCurrTime_NOTDETERMIN ();
• SYSDATE()와 NOW() 함수의 차이는 ?
Real MySQL
http://cafe.naver.com/realmysql
7. IN (subquery)
•[NOT] IN (subquery)는 비효율적
•절대 subquery가 먼저 처리되지 못함
SELECT *
FROM tab outer
WHERE fd IN (SELECT fd FROM tab inner);
+----+--------------------+-------+
| id | select_type
| table |
+----+--------------------+-------+
| 1 | PRIMARY
| outer |
| 2 | DEPENDENT SUBQUERY | inner |
+----+--------------------+-------+
Real MySQL
http://cafe.naver.com/realmysql
8. IN (subquery)
•실행 계획의 의미
+----+--------------------+-------+
| id | select_type
| table |
+----+--------------------+-------+
| 1 | PRIMARY
| outer |
| 2 | DEPENDENT SUBQUERY | inner |
+----+--------------------+-------+
FOR (row1 IN outer){
exist( SELECT * FROM inner WHERE inner.fd=row1.fd )
}
Real MySQL
http://cafe.naver.com/realmysql
9. IN (subquery)
•IN (subquery)
Join이나 Derived 테이블
SELECT *
FROM tab outer, tab inner
WHERE outer.fd=inner.fd;
•NOT IN (subquery)
Anti-Join이나 Dervied를 이용한 Anti-Join
SELECT *
FROM tab outer
LEFT JOIN tab1 inner WHERE inner.fd=outer.fd
WHERE inner.fd IS NULL;
Real MySQL
http://cafe.naver.com/realmysql
10. IN (subquery)
•서브 쿼리에서 중복 제거 필요시
Derived 테이블 이용
SELECT [STRAIGHT_JOIN] *
FROM
(SELECT fd FROM tab inner GROUP BY …) x,
tab outer
WHERE outer.fd = x.fd
•서브 쿼리 내용 상수화
SELECT * FROM tab outer
WHERE outer.fd IN ( 1,2,3 )
Real MySQL
http://cafe.naver.com/realmysql
11. Transaction propagation
• A 데이터베이스의 트랜잭션에 외부 작업 개입
• 마스터와 슬레이브 DB 작업 혼재
BEGIN
UPDATE
SELECT
UPDATE
Commit
master_tbl SET … WHERE …
* FROM slave_tbl WHERE …
master_tbl SET … WHERE …
/ Rollback
Real MySQL
http://cafe.naver.com/realmysql
12. Transaction propagation
• DB 트랜잭션 중간에 외부 네트워크 작업
BEGIN
UPDATE tbl SET … WHERE …
Cassandra or HBase SET …
Send email or some other network job …
Commit / Rollback
Real MySQL
http://cafe.naver.com/realmysql
13. Transaction propagation
• 외부 작업 지연시
MySQL 서버의 레코드 잠금 시간 연장
• MySQL 서버의 Record 잠금 해제 지연 및
다른 세션의 잠금 대기 길어짐
• MySQL 서버는 큰 부하 없이, 아무런 작업도 처리 못함
• UndoRecord와 SystemTablespace ⇧
많은 Undo로 인한 SELECT 성능 ⇩
Real MySQL
http://cafe.naver.com/realmysql
14. Transaction propagation
• 트랜잭션 모니터링
mysql> SHOW ENGINE INNODB STATUS;
-----------TRANSACTIONS
-----------…
---TRANSACTION 3F0B, ACTIVE 23 sec, OS thread id 1252
1 lock struct(s), heap size 320, 0 row lock(s), undo log entries 1
MySQL thread id 1, query id 85 localhost 127.0.0.1 root
...
• Unix 계열 OS
mysql> pager grep ACTIVE
Real MySQL
http://cafe.naver.com/realmysql
15. 한방 쿼리
SELECT
IFNULL(COUNT(fd1),0) as fd1, IFNULL(AVG(fd5),0) as fd4, IFNULL(fd6, 'Y') as fd5,
FROM (
SELECT fd1, fd2, 1 as fd3,
IF(fd4 <> fd6, 0,1) as fd4, IF(fd5 <> fd6, 1,0) as fd5, 0 as fd6 , 0 as fd7, fd8
FROM tab1 a
INNER JOIN tab2 b ON a.fd10 = b.fd10
WHERE b.fd13 IN (1, 2, 3, 4)
AND b.fd14 >= DATE_ADD('2011-10-08', INTERVAL 12 HOUR)
AND b.fd15 < DATE_ADD('2011-10-09', INTERVAL 12 HOUR)
GROUP BY fd1, fd2, fd3
UNION ALL
SELECT 0,0,0,0,0,1,0,a.fd1
FROM tab4 a
LEFT JOIN tab6 b ON a.fd1 = b.fd1
and b.fd11 < DATE_ADD('2013-10-08', INTERVAL 12 HOUR)
and b.fd12 in (12, 13)
WHERE a.fd13 IS NOT NULL
and a.fd15 IN (111,109)
…
…
…
Real MySQL
http://cafe.naver.com/realmysql
16. 한방 쿼리
• 충분한 튜닝 능력과 집중력 필수
– 쿼리를 튜닝해줄 DBA가 있다면 OK
– 만약 튜닝 능력⇩ + DBA가 없다면
내게 익숙한 절차적 개발 언어 적극 활용
• 단순해질수록 고도의 튜닝 능력 불필요
• 잘게 샤딩된 MySQL -> 복잡한 쿼리 X
• 쿼리가 어떻게 작동할지 잘 모르겠다면,
컨트롤이 가능한 수준까지 쪼개에서 실행
Real MySQL
http://cafe.naver.com/realmysql
17. INDEX
• UNIQUE INDEX ?
• PRIMARY KEY 또는 UNIQUE INDEX로 Clustering
• Secondary Index는 PK 포함 (InnoDB)
• 인덱스 많을수록
INSERT UPDATE DELETE ⇩
SELECT 성능 ⇧
Real MySQL
http://cafe.naver.com/realmysql
18. INDEX
• 인덱스 중복과 중첩
INDEX (fd1, pk1) = INDEX (fd1)
UNIQUE INDEX (fd1) ⊃ INDEX (fd1)
INDEX (fd1, fd2) ≠ INDEX (fd2, fd1)
INDEX (pk1, fd1) ≠ INDEX (fd1, pk1)
INDEX (fd1, fd2) ⊂ INDEX (fd1, fd2, fd3)
Real MySQL
http://cafe.naver.com/realmysql