Category: MySQL

This is MySQL

MySQL USING VS ON 차이.

MySQL에서 JOIN 을 사용할때에 USING 이나 ON 을 사용한다. 결과적으로 뽑고자 하는 데이터는 모두 동일한데 과연 이둘의 차이는 무엇일까?

첫째로 사용법에서 차이가 있다. USING 은 두 테이블간 필드이름이 같은 경우에 사용한다.

employees 와 salaries 를 조인(JOIN)하는데 emp_no 를 키가 양쪽 테이블에 모두 있기 때문에 USING 을 사용할 수 있다.
하지만 만일 조인시에 컬럼 이름이 다를 경우에는 ON 을 사용한다. 물론, 컬럼 이름이 같은 것을 기반을 조인을 할때도 ON 을 상용해도 된다.

Creative Commons License
MySQL USING VS ON 차이. by Voyager of Linux is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

[번역] 5.6과 5.7 사이의 MySQL 기본 설정 변경.

이 글은 다음의 글을 번역한 것입니다. 전문 번역자가 아니기에 오류가 있음을 미리 밝힙니다.
https://www.percona.com/blog/2016/09/14/mysql-default-configuration-changes-between-5-6-and-5-7/

이 블로그에서, 우리는 MySQL 5.6 과 5.7 사이에 기본 설정값의 차이에 대해 논의할 것이다.

MySQL 5.7 은 여러분이 기대했던 다양한 새로운 기능이 추가되었다. 하지만, 현재 변수들 또한 알게모르게 변화가 있었다. MySQL 5.7은 5.6으로부터 거의 40개의 기본값이 변경되었다. 어떤 바뀐값들은 여러분의 서버 성능에 아주 크게 영향을 줄 것이고 어떤것은 알지도 모르체 넘어갈 거다. 나는 각각의 변화가 무엇이고 어떤 의미인지를 살펴볼 것이다.

sync_binlog 와 같은 값들은 여러분의 서버에 아주 큰 영향을 줄 수 있다. 내 동료는, Roel Van de Paar, 다른 블로그 글을 통해서 아주 상세하게 sync_binlog의 영향을 깊게 다뤘다. Sync_binlog 는 어떻게 MySQL이 binlog 를 디스크로 플러시(flush)하는지를 제어한다. 새로운 값 1은 MySQL에게 커밋(Commit) 하는 동안 모든 트랜잭션들을 디스크로 쓰도록 강제한다. 이전에는 binlog 를 플러싱하도록 강제하지 못했었고 OS가 binlog를 플러시하는 시점을 결정하는걸 그져 신뢰해야만 했다.(OS 가 binlog 를 플러시하도록 내버려뒀다.)
https://www.percona.com/blog/2016/06/03/binary-logs-make-mysql-5-7-slower-than-5-6/

Variables5.6.295.7.11
sync_binlog01

퍼포먼스 스키마 변수들은 유용하지 않은것처럼 보이지만, 많은 것들이 기본값이 -1 이다. MySQL은 자동적으로 조정되어지는 변수들을 호출하는데 이 표기법을 사용한다. 오직 performance_schema_max_file_classes 만이 (자동으로) 조정되지 않고 바뀐다. 이것은 퍼포먼스 스키마에서 사용되어지는 파일 명령어들의 숫자다. 이것은 당신이 바꿀 필요가 없는 값이다.

Variables5.6.295.7.11
performance_schema_accounts_size100-1
performance_schema_hosts_size100-1
performance_schema_max_cond_instances3504-1
performance_schema_max_file_classes5080
performance_schema_max_file_instances7693-1
performance_schema_max_mutex_instances15906-1
performance_schema_max_rwlock_instances9102-1
performance_schema_max_socket_instances322-1
performance_schema_max_statement_classes168-1
performance_schema_max_table_handles4000-1
performance_schema_max_table_instances12500-1
performance_schema_max_thread_instances402-1
performance_schema_setup_actors_size100-1
performance_schema_setup_objects_size100-1
performance_schema_users_size100-1

optimizer_switchsql_mode 변수들은 각각 활성화될수도 있고 약간 다른 행동을 유도하게할 수도 있다. MySQL 5.7 에서는 민감도와 보안이 향상시키는데 플래그를 두가지 변수값을 활용할 수 있다.(활성화하거나 다른행동을 하게하도록 값을 지정하는 행위) 이것은 추가적으로 옵티마이저에게(Optimizer) 여러분들의 쿼리가 정확하게 해석되도록 결정하는데 좀더 효율성을 제공한다.

optimzer_switch 에 추가된 세개의 플래그들, 모두 MySQL 5.6 에 존재하며, 옵티마이저의 효율성을 높이기위한 목적으로 MySQL 5.7의 기본값으로 설정되었다. duplicateweedout=on, condition_fanout_filter=on 그리고 derived_merge=on. duplicateweedout 은 옵티 마이저의 세미 조인 구체화 전략의 일부입니다. condition_fanout_filter 은 조건 필터링 사용을 제어하고 derived_merge은 derived 테이블의 머지를 제어하고 뷰를 외부쿼리 블럭으로 제어한다.

https://dev.mysql.com/doc/refman/5.7/en/switchable-optimizations.html

http://www.chriscalender.com/tag/condition_fanout_filter/

(위 설정들을) SQL mode 에 추가해도 직접적으로 성능에 영향을 주지 않지만 성능을 높일수 있는 쿼리 작성법을 개선해준다. 몇몇 주목할만한 변화로 select … group by 문에서 모든 필드를 요구하려면 SUM과 같은 함수를 사용하여 집계하거나 group by 절에 넣어야한다. MySQL은 그룹화해야 한다고 가정하지 않으며, 필드가 없는 경우 오류를 발생시킨다. Strict_trans_tables 는 트랜잭션 테이블과 함께 사용되는지에 따라 다른 효과를 발생시킵니다.

명령문은 그것이 유효하지 않거나 데이터 변경을 위한 명령문에서 값이 누락된다면 트랜잭션 테이블은 롤백되었었다. 트랜잭션 엔진을 사용하지 않는 테이블에서 MySQL은 유효하지 않은 데이터가 발생한 레코드에 의존해 행동한다. 첫번째 row 라면 트랜잭션 엔진의 동작과 똑같이 동작하진다. 만일 그렇지 않다면 유효하지 않은 값은 가장 근사한 유효한 값 혹은 컬럼의 기본값으로 변경되어진다. 경고는 발생되지만 데이터는 insert 된다.

Variables5.6.295.7.11
optimizer_switchindex_merge=on
index_merge_union=on
index_merge_sort_union=on
index_merge_intersection=on
engine_condition_pushdown=on
index_condition_pushdown=on
mrr=on,mrr_cost_based=on
block_nested_loop=on
batched_key_access=off
materialization=on, semijoin=on
loosescan=on, firstmatch=on
subquery_materialization_cost_based=on
use_index_extensions=on
index_merge=on
index_merge_union=on
index_merge_sort_union=on
index_merge_intersection=on
engine_condition_pushdown=on
index_condition_pushdown=on
mrr=on
mrr_cost_based=on
block_nested_loop=on
batched_key_access=off
materialization=on
semijoin=on
loosescan=on
firstmatch=on
duplicateweedout=on
subquery_materialization_cost_based=on
use_index_extensions=on
condition_fanout_filter=on
derived_merge=on
sql_modeNO_ENGINE_SUBSTITUTIONONLY_FULL_GROUP_BY
STRICT_TRANS_TABLES
NO_ZERO_IN_DATE
NO_ZERO_DATE
ERROR_FOR_DIVISION_BY_ZERO
NO_AUTO_CREATE_USER
NO_ENGINE_SUBSTITUTION

binlog 와 관련해 몇가지 변수가 변경되었다. MySQL 5.7 에 binlog_error_action가 업데이트 됐는데, binlog 를 쓰는중에 오류가 있다면 서버는 중단된다. 이런 일은 흔하지 않지만, 이런일이 발생하면 여러분의 애플리케이션과 리플리케이션에 큰 피해를 발생시키고 그것이 고쳐질때까지 서버는 그 어떤 추가적인 트랜잭션도 실행하지 않는다.

binlog 의 기본 포맷도 이전의 statement 대신에 ROW 로 변경되었다. Statement 는 로그에 적은 데이터를 쓴다. 하지만 많은 명령문들이, update … order by rand()을 포함해, 정확하게 복제되어지지 않았었다. 이러한 비결정적인 명령문은(non-deterministic statements) 마스터와 슬레이브에서 서로 다른 결과셋을 가진다. ROW 포맷으로 변화는 좀 더 많은 데이터를 binlog 에 쓰지만, 정보가 정확하고 올바른 복제를 보장한다.

MySQL은 전통적인 binlog 포지션 방식대신에 GTID 를 사용하는 리플리케이션에 초점을 맞추기 시작했다. MySQL이 시작하거나 재시작할때, 이전에 사용된 GTID 의 목록을 생성해야 한다. 만일 binlog_gtid_simple_recovery가 OFF거나 FALSE 라면 서버는 새로운 binlog 로 시작하고 previous_gtids_log_event 대해서 binlog 파일 검색을 거꾸로 반복한다. 만일 이것이 ON, True 라면 서버는 최신과 가장 오래된 binlog 파일을 검토하고 사용된 gtid 를 계산한다. Binlog_gtid_simple_recovery는 binlogs 를 좀 더 빠르게 파악하게 해주며, 특히 GTID 이벤트가 없는 아주 많은 수의 바이너리 로그를 빠르게 파악해준다. 하지만, 특별한 경우에 이것은 gtid_executedgtid_purged 가 잘못 채워질 수도 있다. 이것은 오직 MySQL 5.7.5 나 그 이후버전에 의해서 새로운 binlog 가 생성되어질때 발생하거나 SET GTID_PURGED 명령문이 5.7.7 보다 이전버전에서 실행될때 발생된다.

5.7에서 업데이트된 또다른 리플리케이션 기반 변수는 slave_net_timeout 이다. 이것은 60s 미만이여야 한다. 이전 버전의 리플리케이션 쓰레드는 적어도 한 시간에 문제가 발생될때까지 마스터로 연결이 깨졌다고 판단하지 않았다. 이 변화는 연결에 문제가 있다는 것을 좀더 빠르게 알려주고 여러분이 이슈를 알기전에 복제가 크게 뒤쳐지지 않도록 해준다.

Variables5.6.295.7.11
binlog_error_actionIGNORE_ERRORABORT_SERVER
binlog_formatSTATEMENTROW
binlog_gtid_simple_recoveryOFFON
slave_net_timeout360060

InnoDB 버퍼 풀 변경은 서버 시작 및 중지 시간에 영향을 준다.

innodb_buffer_pool_dump_at_shutdowninnodb_buffer_pool_load_at_startup 는 서버를 ‘warm up’ 하지 못하도록 함께 쓰인다. 이름처럼, 이것은 셧다운시에 버퍼풀 덤프를 유발하고 시작시에는 로드 된다. 비록 여러분이 100Gb 용량의 버퍼풀을 가지고 있어도, 쓰여진 데이터는 훨씬 작기 때문에 버퍼풀 용량과 똑같은 디스크 용량을 확보할 필요는 없다. 디스크에 쓰여지는 것은 실제 데이터, 테이블공간 과 페이지ID 를 찾는데 필요한 정보만이다.

Variables5.6.295.7.11
innodb_buffer_pool_dump_at_shutdownOFFON
innodb_buffer_pool_load_at_startupOFFON

이제 MySQL 은 5.6과 그 이전 버전에 InnoDB 에 구현된 몇가지 옵션들을 기본값으로 만들었다. InnoDB 의 체크섬 알고리즘을 innodb 에서 crc32로 개선했는데, 이는 최근 Intel CPU 의 하드웨어 가속 기능을 활용할 수 있는 장점이 있다.

Barracuda 파일 포맷은 5.5 이후부터 활용되기 시작해 5.6 에서 많은 개선이 이루어졌으며 이제 5.7 에서는 기본값이 되었다. Barracuda 포맷은 압축과 동적 로우 포맷을 사용할 수 있다. 내 동료 Alexey 는 압축된 포맷의 사용과 최적화 때 그가 본 결과에 대해서 글을 썼다. https://www.percona.com/blog/2008/04/23/real-life-use-case-for-barracuda-innodb-file-format/

innodb_large_prefix 는 기본값이 ‘on’ 이며 Barracuda 파일 포맷과 조합해서 사용할 경우에 좀 더 큰 index key prefix 를(3072 bytes보다 큰) 생성할 수 있다. 이것은 아주 큰 텍스트 필드의 인덱스에서 장점이 된다. 만약 이것이 ‘off’ 라면, 로우 포맷은 동적이거나 압축이 되지 않으며, 767 bytes 보다 큰 index prefix는 자동으로 잘린다. MySQL은 5.7.6에서 더 큰 InnoDB 페이지 크기 (32k 및 64k)를 도입했다.

MySQL 5.7 은 innodb_log_buffer_size 값이 충분히 커졌다. InnoDB 는 바이네리 로그에 디스크로 쓰는 동안에 로그 트랜잭션를 위한 로그 버퍼를 사용한다. 증가된 크기는 로그를 디스크로 플러쉬하는 빈도를 줄이고, I/O를 줄이며, 커밋하기 전에 디스크에 기록 할 필요없이 로그에보다 큰 트랜잭션을 저장할 수 있다.

MySQL 5.7 은 MySQL 5.5 에서 thread contention 을 줄이기 위해서 InnoDB의 퍼지 연산들을 백그라운드 쓰레드로 옮겼다. 최신 버전에서 퍼지 쓰레드는 4개로 기본값이 늘었지만 1에서 32쓰레드까지 언제든지 변경할 수 있다.

MySQL 5.7 은 이제 innodb_strict_mode 가 기본값이 됐고 몇몇 경고들은 오류로 바뀌었다. create table, alter table, create index, optimize table 명령문에서 문법 오류는 에러를 발생시키고 실행전에 사용자가 수정해야만 한다. 또 insert 나 update 구문이 선택한 페이지 크기에 비해 아주 큰 레코드 때문에 실패하지 않도록 레코드 크기를 체크할 수 있다.

Variables5.6.295.7.11
innodb_checksum_algorithminnodbcrc32
innodb_file_formatAntelopeBarracuda
innodb_file_format_maxAntelopeBarracuda
innodb_large_prefixOFFON
innodb_log_buffer_size838860816777216
innodb_purge_threads14
innodb_strict_modeOFFON

MySQL 은 equality 범위를 평가할때 옵티마이저가 index로 넘어가는 횟수를 증가시켰다. 만약 옵티마이져가 eq_range_index_dive_limit 보다 더 많이 index로 넘어가길 원한다면, MySQL 5.7 에서 기본값 200, index 통계를 사용한다. 여러분은 이것을 0부터, 인엑스 다이빙 제한, 4294967295 까지 수정할 수 있다. 이것은 테이블 통계가 무작위 샘플의 카디널리티를 기반으로 하기 때문에 쿼리 성능에 큰 영향을 줄 수 있다. 이로 인해 최적화 프로그램은 인덱스 다이빙보다 검토 할 훨씬 많은 행 집합을 평가하고, 옵티마이 저가 쿼리를 실행하기 위해 선택한 방법을 변경하게 할 수 있다.

MySQL 5.7 에서 log_warnings 은 사라졌다. 대신 log_error_verbosity 를 사용된다. 기본값은 3이고 에러로그에 errors, warnings, notes 가 기록된다. 여러분은 이것을 1(errors 만) 이나 2(errors 와 warnings) 로 변경할 수 있다. 에러 로그를 참조할때, verbosity 는 좋은 것이다. 하지만 이것은 error 로깅을 위해서 디스크 공간과 I/O를 증가 시킨다.

table_open_cache_instances 는 MySQL 5.7.8 부터 변경 되었다. instance 의 숫자는 1에서 16까지 증가된다. 이것은 두가지 장점이 있는데, DML 구문의 contention 을 줄여주고, 캐쉬 접근의 세분화 된다. instance 수를 증가시킴으로써, DML 구문은 전체 캐쉬가 아닌 하나의 instance 만 잠글수 있다. 한가지 중요한 사실은 DDL 구문은 여전히 전체 캐쉬에 잠금(lock)를 필요로 한다. 시스템에서 많은 수의 세션이 캐쉬에 접근하면 성능은 증가 된다.

Variables5.6.295.7.11
eq_range_index_dive_limit10200
log_warnings12
table_open_cache_instances116

5.7 에서 기본값에 많은 변경이 있다. 하지만 이렇게 많은 옵션들은 오랫동안 존재해왔고 사용자에게 친숙해야 한다. 많은 사람들이 이 변수들을 사용했고 그들은 MySQL을 앞으로 나가게 하는 가장 좋은 방법이다. 하지만 기억해야 할 것은, 여러분은 여전히 이러한 변수들을 편집할 수 있고 서버가 여러분의 데이터를 위해 최고 동작하도록 그들을 설정할 수 있다.

Creative Commons License
5.6과 5.7 사이의 MySQL 기본 설정 변경. by Voyager of Linux is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

[번역] MySQL 5.7.6 릴리즈. 큰 변화에 준비하자.

이 글은 “MySQL 5.7.6 is out. Be prepared for big changes” 를 원작자의 허락을 받아 번역한 것입니다. 원본은 아래의 주소에 있습니다. 번역을 허락해준 Giuseppe Maxia 씨에게 감사 합니다.

오늘 오라클(Oracle)이 MySQL 5.7.6 마일스톤 16을 릴리즈(Release) 했다. 이것으로 MysQL 5.7 은 개발에 2년이 넘게 소요됐다. MySQL 5.6과 비교해 바뀐점은 아주 넓다. 주요한 팀(개발 팀)의 노력은 이전 릴리즈와 비교해 2배에서 3배의 성능 향상을 가지는 , MySQL 의 동작,스피드에 포커스를 맞춰왔다. 무엇이 새로운지에 대한 전체 리스트는 여기에 가지고 오기에는 너무나 많은 공간이 필요해, 나는 몇가지 키포인트들만 언급할 것이다.

  • 오라클은 MySQL 보안과 안전성 개선에 상당히 많은 에너지를 소비했다. 많은 새로운 기능을 볼수 있겠지만 아주 오래된 기능들은 deprecated 되었고 5.6에서 deprecated 된것들은 삭제되었다.
  • 설치과정은 MySQL 5.7 릴리즈되는 매 마일스톤마다 항상 좀 더 향상되는 것을 목표로 바뀌어왔다.하지만 이러한 노력은 이전버전과의 호환성을 깰 것이다.

이 기사에서는 나는 설치과정에서 크게 바뀐 부분을 언급할 것이다. MySQL 5.6 에서 mysql_install_db 는 데이터베이스 생성중에 랜덤 패스워드 생성기에 대한 옵션을 가지고 있다. 이 과정은 익숙하지 않지만 오랜시간동안 패스워드없이 root 사용자를 생성하도록 했던것을 직접적으로 끝장을 내는 행보였다. MySQL 5.7.4 에서, 그것은 좀더 바뀌어서, 랜덤 패스워드 생성기는 -skip-random-password 옵션으로 건너뛸 수 있지만 어쨌든 기본값이 됐다. MySQL 5.7.5 에서, 기본은 확정되었고 옵션은 -insecure 로 바뀌었다.

그리고 이제, MySQL 5.7.6 에서, 오래된 관행을 단속하고자: mysql_install_db 는 deprecated 됐고 mysqld -initalize 로 바뀌었다. (예전에 “mysqld -bootstrap” 으로 알려졌던 것은 현재 deprecated 됐다)

여기서 테스트 해보자:

이전 버전과 비교해, 가장 주목할 차이는 .mysql_secret 파일이 없다는 것이고 스크린에 임시 패스워드가 짧은 줄로 언급된다. 또, 한가지 더 중요한 행동상의 차이점으로 이 명령어는 오직 한번만 작동한다. 만약 데이터 디렉토리가 존재한다면, 그 스크립트는 데이터 생성 명령어들을 다시 적용할려고 할 것이다. mysqld -initialize 사용은 데이터 디렉토리가 존재하지 않을때에만 실행된다.

새롭게 생성된 데이터베이스 사용을 위해서는 이전과는 다른 꼼수가 있다.

우잉? 이게 뭘까? 이 명령어는 최근까지 잘 동작했다. 원인은 SET PASSWORD 문법이 변경되었는데 이제는 생자 텍스트를 인수로 받는다.

오래된 문법은 오직 deprecated 되었다는걸 뜻하지만 이것은 순간적으로 완벽하게 제거될 수 있다. 이것은 MySQL 5.7.7 에서 고쳐지길 희망한다. (뭔소리냐.. ㅡㅡ;;)

더 많은 변화는 GRANT, REVOKE, CREATE USER, 그리고 ALTER USER 사용에서 일어났는데 현재 좀 더 제한적이다. 만약 GRANT 명령어로 사용자들을 생성하려고 한다거나 승인권한을 인증옵션과 섞으려고할때에 경고 메시지를 받을 수 있다.

요컨대, 만약 MySQL을 설치하고 관리하는 자동화된 스크립트를 가지고 있다면, 당신은 waringins 을 활성화하고 테스트해야 한다, 오래된 관습을 가지는 호환성이 깨지는것에 대비해야 한다.

One such ‘old practice’ scripts that is broken by the new syntax changes is MySQL-Sandbox. I have just released an updated version (MySQL Sandbox 3.0.48) with a workaround for MySQL 5.7.6 changed SET PASSWORD syntax.

BTW, mysql.user 테이블에 password 필드가 삭제되었다고 말했나요? 이것은 많은 테스트를 멈추게하는 또 다른 놀라운 점이다.

 

Creative Commons License
[번역] MySQL 5.7.6 릴리즈. 큰 변화에 준비하자. by Voyager of Linux is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

MySQL joins: ON vs. USING vs. Theta-style

Mariadb 이 글은 다음에 글을 ‘내 마음대로’ 번역한 것 입니다.

http://code.openark.org/blog/mysql/mysql-joins-on-vs-using-vs-theta-style

다음 3개의 문법에 차이는 무엇인가?

차이점이라면 외형적으로 문법적인 것 외에 없는데, 여기에 흥미로운점이 있다.

이름을 붙이자면, 위에 두개는 “ANSI-style” 마지막 세번째는 “Theta-style” 이라고 한다.

Theta style (세타 스타일)

FROM 구문에, Cartesian 연산을 할 경우에 테이블 리스트, 그리고 WHER 구문에는 어떻게 join 할지를 정의하는 것을 놓는다.

이것은 “old” 스타일로 여겨진다. 이것은 다소 읽기에 혼란스럽다. 다음과 같은 쿼리를 생각해보자.

위 쿼리는 배우 아이디 17이고 필름길이(아마 상영시간인듯) 120분 이상인 필름들을 리스트 한다. 결과에 신경쓰지 말고, 위 쿼리는 무엇인가? WHERE 구문 부분에 존재하는 하나인, AND 표현식에 3개의 엘레멘트중 하나,   조인식은 제외된다. 조인식을 찾기도 힘들도 레코드를 필터하는 문장과 대조적으로 테이블 조인을하는 문장을 구분해 내기도 힘들다. 위 예제에서는 그래도 포인트를 찾기가 쉽다. 5개의 테이블, 20개의  문장을 가진 WHERE 구분 쿼리는 어떻게 할거냐?

ANSI style: ON

JOIN .. ON 에서, 필터링 문장(아마 WHERE 구문을 말하는듯.) 으로부터 조인문장을 분리한다. 앞에 예제를 다시 작성하면 다음과 같다.

이제 무엇을 조인하는지 명확해 졌다.

Note: the parenthesis are not strictly required in the ON clause. 개인적으로 나는 이것을 사용하는것을 좋아한다. 이것은 쿼리 파트사이에서도 아주 큰 차이를 만든다. SQL 문법은 지저분하다.

ANSI style: USING

특별한 경우로 테이블을 조인할 때에 각 테이블에 같은 이름의 컬럼이 존재하면 우리는 USING 을 사용해서 다음과 같이 짧게 작성할 수 있다.

This time the parenthesis are required (I’m not sure why the difference on that part).

이것의 세세한 차이점이라고는 단어를 적게 치거나 결과적으로 아름다운 쿼리정도다. But also note a couple differences:

USING vs. ON

다음은 유효한 구문이다.

하지만 다음은 유효하지 않다.

USING은 양쪽 테이블에서 film_id 가 공유되어진다는 사실을 알고 있는거라면, 우리는 정밀한 테이블의 정의를 물어볼 필요가 없다. 이것은 항상 같은 값이 존재한다.

ON 스마트 하지 않고 좀더 명확한 것을 필요로 한다: 당신이 원하는 것이 정확하게 어느테이블에 있는냐?

위의 실질적으로 흥미로운 현상의 결과는 다음과 같다.: USING을 사용할때에 결과에서 컬럼은 한번 나타난다.

그런데, ON  조인에서는 컬럼이 두번 나타난다.

Behind the scenes

MySQL은 모두 같은 방법으로 모든 쿼리를 다룬다. EXPAIN EXTENDED 의 도움을 받아서 그것을 볼수 있다.

모든 쿼리는 내부적으로 theta-style 로 변환된다.

이 포스트는 inner joins 만 다룬다. outer joins 상황에서는 다소 차이가 있을 수 있다.

Creative Commons License
MySQL joins: ON vs. USING vs. Theta-style by Voyager of Linux is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.