DLife Planet

[쿼리 공부] 기초 1 모든 레코드 조회하기 (Select ALL) 본문

DataScience

[쿼리 공부] 기초 1 모든 레코드 조회하기 (Select ALL)

Western_Gem 2020. 11. 18. 23:32
반응형

어디 가서 SQL 나름 중수라고 떠들고 다니는 데, 기초도 좀 다질 겸, 공부도 틈틈이 할 겸 포스팅 좀 써볼까 해요.

대망의 첫 콘텐츠!

[제 포스팅의 예상 독자 - 중 하수]

기준 : 단순히 결과만 내는 게 목적이 아닙니다.

제 SQL 포스팅은 무조건 실전형입니다. 그러므로, 최소한 쿼리 기초 강좌를 수강하셨거나 한번 셀렉트 쿼리를 한두 번은 써 본 사람들 입장에서 쓰겠습니다. 그렇다고 원리를 제대로 파악 안 하고 문법을 외우는 게 목적은 아닙니다.

같은 결과를 내더라도 더 성능상 나은 쿼리가 무엇인지, 원리적으로 접근해서 포스팅을 할까 합니다.

 

바로 실전 첫 문제로 들어갈게요.


출처 - 프로그래머스

[해설] 

모든 프로그래머스 SQL 문제들은 테이블 명, 테이블 스키마(테이블의 구성), 쿼리 목표, 그리고 예시로 구성이 됩니다.

이 문제는 Select * from [tab] order by [col] 문법을 가진 기초 문제입니다. 즉 ANIMAL_INS 테이블 전체 값을 ANIMAL_ID로 정렬해서 출력한다는 쿼리를 작성하면 됩니다. 


[정답]

전 세계 99%의(제 뇌피셜이지만 거의 모두 동의하는 부분) RDBMS SQL문법은 Oracle 아니면 Mysql로 정리가 됩니다. (SQL Server혹은 임베디드 SQL의 문법이 나머지 1%라고 봅니다. 사실상 많이들 안 쓰죠... 물론 어디까지나 제 뇌피셜입니다. 제 주장을 반박하시거나 동의하시는 고인이 있으시다면 댓글로 달아주세요. 전 컴공 전공자가 아닙니다. 하지만, 김풍 형도 냉부해에서 요리 지식 자랑하잖아요 ㅋㅋ)

 

그래서, 어쨌거나 저쨌거나 프로그래머스에서도 Mysql과 Oracle 두 가지 버전의 쿼리를 요구합니다. 꼭 프로그래머스가 아니더라도 공부하실 때 두가지 문법만 고려하시면 될 거 같습니다.

 

Mysql 문법 정답

SELECT * from ANIMAL_INS order by ANIMAL_ID;

Oracle 문법 정답

SELECT * from ANIMAL_INS order by ANIMAL_ID;


[SQL Insight]

사실 1번 문제에는 엄청 거창한 이론은 없습니다.

 

그래서, 대신 쿼리 작성 혹은 튜닝 시 지켜야 할 가장 기본 원칙을 먼저 소개할까 합니다.

모래성에 지은 집은 무너지듯, 개념을 제대로 잡고 기초 쿼리를 작성해 버릇해야

작성해야 자신의 실력을 키우는 잠재력이 더 커진다라는 철학이 있습니다.

출처 https://campus.datacamp.com/courses/improving-query-performance-in-sql-server/introduction-review-and-the-order-of-things?ex=8

네, Datacamp에서 수업을 하시는 저명한 강사님께서 말씀하시길, Select 쿼리의 논리적 순서라고 하네요.

 

숫자가 클수록 지양하라고 하네요. 다만 모두가 알다시피 7번 Select는 필수 불가결한 요소입니다.

 

이 원칙은 어디까지나 대용량 테이블을 기준으로 하는 말이며, 소량의 데이터를 처리할 때는 각각의 함수들이 최적화가 돼있기 때문에 직관적으로 쓰는 센스를 발휘해야 한다 등 갑론을박이 발생하는 부분이기도 합니다.

하지만 확실한 것은, SELECT 이후의 구문은 데이터베이스 처리 리소스를 사용해야 하며 필요한 경우에만 사용해야 합니다.

(남용하면 성능 저하를 부른다는 것은 거의 공론화된 사실, order by는 대체 불가, 고로 Distinct를 지양하란 뜻으로 봅시다. 중복된 애를 불러오고 지우지 말고, 애초에 중복 출력을 하지 말란 뜻, TOP은 ROWNUM과 LIMIT으로 쓰입니다. )

 

Join을 쓸 경우 대체될 수 있는 기능은 성능상 on > where > having이며

Group By는 Where와 Having의 중간쯤 된다고 하네요.


이 밖에 튜닝을 위해 필요한 개념, 제가 앞으로 쭉 참고할 듯한 방법론인데요.

 

medium.com/watcha/%EC%BF%BC%EB%A6%AC-%EC%B5%9C%EC%A0%81%ED%99%94-%EC%B2%AB%EA%B1%B8%EC%9D%8C-%EB%B3%B4%EB%8B%A4-%EB%B9%A0%EB%A5%B8-%EC%BF%BC%EB%A6%AC%EB%A5%BC-%EC%9C%84%ED%95%9C-7%EA%B0%80%EC%A7%80-%EC%B2%B4%ED%81%AC-%EB%A6%AC%EC%8A%A4%ED%8A%B8-bafec9d2c073

저보단 글을 잘 쓰는 듯... 분하니까 요약이라도 해야지

 

1. 칼럼명을 *보다는 명시적으로 쓰라고 하네요. ( Select * from tab (X) / Select col1, col2,... , coln from tab (O))

 

2. 쿼리에서 사칙연산 등 연산을 넣는 것을 지양하라네요 (데이터 엔지니어가 아니라면, 데이터 사이언스 코딩 혹은 애플리케이션 코딩을 생활화합시다. FLOOR 함수, 사칙연산 등)

 

3. LIKE를 쓸 때는 가급적 'String%'만 쓰라고 하네요.

 

4. 이분도 DISTINCT는 극혐 하네요. 대신 EXIST를 써서 원 테이블의 출력 값을 필터링하라고 하는군요. (깊이 반성합니다. 자칭 중수 주제에 상당히 못 지킨 부분)

 

5. 이분도 having보다는 where를 쓰라고 하네요. 첨언을 하자면 위에 써놨듯 join을 쓸 경우엔 on이 더 유리하겠네요.

 

6. 오우... 현기증 나는 JOIN 문법에 대한 설명이군요. (SQL 5년 차인데, 아직도 헷갈림...) Inner Join을 할 때는 테이블을 오름차순 하라고 하네요. (inner join 대상 테이블의 교집합 로우만, left는 A, right는 B의 레코드를 기준으로, Full은 모든 테이블을 기준으로... 아아 복잡하니까 이해 안 되시면 가서 공부하세요. 개념만 이해하시면, oracle mysql문법 약간 다른 것도 찾아보시면서 하면 금방 이해될 거예요. 그냥, 위에 언급한 4가지만 이해해 보세요)

stanleykou.tistory.com/entry/SQL-INNER-%EC%A1%B0%EC%9D%B8%EA%B3%BC-OUTER%EC%A1%B0%EC%9D%B8%EC%9D%B4-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80%EC%9A%94

결론, outer 조인의 경우 어느 한쪽을 기준으로 데이터를 늘리는 거라 애초에 성능상 뭐가 낫다고 말하기 뭐해요.

Union 역시도... 마찬가지지만 UNION 처리를 한 번에 하는 UNION ALL이 짐작컨대 단순 UNION보다는 나아 보입니다.

join을 안 쓴 N*N 카타시안 조인은... 음 Full outer조인에 중복까지 들어갑니다. (아주 나쁜 버릇, 배우지도, 쓰지도 마세요 Join 안쓴 Join이 바로 카타시안 조인... 상당히 나쁜 버릇, 그걸로 코딩한 분들은 아주 그냥 가서 줄 빠 따를 치고 싶음)

 

inner 조인으로 교집합을 계산할 때는 작은 집합끼리 먼저 비교하는 게 비교 횟수가 줄어드니 단순 비교 연산이 줄어서 편하겠죠?  중1 때 집합 공부 열심히 하셨다면 충분히 이해하리라 봅니다.

 

7. 분석용 혹은 SQL 테스트용 테이블은 따로 관리하랍니다. BigQuery(뭔 놈인지 소개할게요) 같은!

 

부담 없이 쉽고 짧은 글을 쓸려했는데, 역시나 튜닝은 고차원적인 영역이라, 쓰다 보니 길어졌네요.

초장에 고수가 되고 싶으시다면, 이 개념들을 이해하는 습관을 들이셨으면 해요.

저처럼 어느 정도 애매하게나마 알고 난 다음에 무릎을 치면서 배워도 됩니다만 첨부터 제대로 익히고 싶으신 이론 파라면 꼭 이런 측면에서 성능관리의 중요성을 먼저 숙지하시길!

 

다른 무엇보다도, 쿼리 작성하는 사람은 그냥 단순 노동자 취급받지만, 튜닝이 가능한 사람은 데이터 과학자로 우대받는 세상이랍니다. 이 글을 읽어주신 분들과 저자인 저까지 우리는 최소한 SQL에 있어서는 데이터 과학자가 됩시다.

 

길고 긴 글을 읽어주셔서 감사합니다.

반응형
Comments