복잡하게 생겼지만 subquery로 질의 한번 vs 간단하게 생긴 쿼리 두번 질의 0 4 835

by 음미 [SQL Query] [2018.07.24 16:44:43]


안녕하세요~ 처음 글써보네요.

 

node.js로 서버 구축하면서 mysql을 사용하고 있는데요.

데이터를 INSERT하려고 하는데 예전에 데이터를 입력했으면(user_id, written_date 쌍이 존재하면) 더이상 INSERT 되지 않게 만들고 싶은데요.

 

요리조리 검색해서 만든 쿼리가 아래와 같습니다.

방법1)

INSERT INTO users_day 
(user_id, written_date, upload_datetime, `stand_up`,`lie_down`)
 SELECT * FROM (SELECT 11,'2018-07-09’, NOW(), '09:00','00:30') as tmp 
WHERE NOT EXISTS(SELECT * FROM users_day WHERE user_id=11 and written_date='2018-07-09’);

돌려보니 속도가 느리지는 않은데 subquery도 있고 복잡하게 생겨서요.

다른 방법으로

방법2)

SELECT * FROM users_day WHERE user_id=11 and written_date='2018-07-09’)로 먼저 data가 있는지 확인하고 있으면 넘어가고 없으면 INSERT하는 방법으로 생각했습니다.

 

 

그래서 드리고 싶은 질문은요.

질문1)
subquery가 있으면 보기에만 복잡한거지 더 느려지고 이런건 없나요? 이 자료에서 보니 subquery는 main query 이전에 실행된다고 하는데 방법1에서 WHERE NOT EXISTS 함수 안에 subquery가 먼저 실행되고 EXIST한것으로 판단되면 그냥 main query insert나 select 는 실행하지 않아서 방법2와 속도가 같거나 더 빨라지나요?

질문2)
written_date와 user_id를 하나로 묶어서 하나의 primary key 처럼 사용할 수 있는 방법은 혹시 없을까요? primary key가 이미 있을때에는 더이상 추가가 안되는게 생각이 나서 여쭤봅니다.

질문3)
기본적인 서버공부랑 간단한 sql문 정도만 공부했습니다. 어떤 쿼리가 더 합리적인 쿼리인지 고민할때마다 어떤걸 공부하면 잘 판단할 수 있을까 고민하게 되는데요. 어떤 부분을 공부하면 좋을지 추천해주시면 감사하겠습니다.

 

좋은하루 되세요~ 

 

by 아발란체 [2018.07.24 17:15:19]

질문1에 대해

서브쿼리를 적절하게 잘 쓰면 성능이 좋아지기 때문에 성능이 좋아진 서브쿼리 구문 경우 쿼리가 복잡하다 라고 보지 않는 것이 좋을 것 같습니다.

사용하신 질의는 서브쿼리 부분 대상 건수가 많을 경우 프로그램 로직으로 분리한 것보다 성능이 나빠질 가능성을 가지고 있습니다.

어차피 단건 입력을 위해 해당 날짜게 데이타가 없는지는 보는 것이기 때문에 서브쿼리에서 추가 조건절로 ROWNUM = 1 등으로 브레이크를 걸어주고, 서브쿼리 조회 내용도 상수 등 사용하여 INDEX FAST SCAN하여 인덱스만 보도록 해주는 것이 좋을 것 같습니다. 이게 어려울 것 같다면 말씀주신 2번째 방법이 좋아보입니다.

 

질문2에 대해

늘상 조회 조건이 written_date + user_id 형태이고 그 값이 고유할 수 있다면 이것으로 기본키를 잡던가 아래처럼 유니크 인덱스를 생성하여 무결성을 유지하는 것도 좋을 것 같습니다.

CREATE UNIQUE INDEX IDX_USERS_DAYS_COMPLEX ON USERS_DAY(written_date, user_id); 

단 written_date와 user_id 중 데이타 선별력이 높은 속성이 먼저 기술되어야 하는데 작성하신 쿼리처럼 늘상 등치 조건이라면 이 경우는 순서 상관 없습니다.

 

질문3에 대해

전문 서적 추천드립니다. 요즘 좋은 책이 많습니다. 

업계 유명한 "성능고도화"와 같은 저자가 보다 쉽게 풀어 1권으로 최근에 출간한 조시형씨가 쓴 "친절한 SQL" 추천드립니다.

 


by 음미 [2018.07.25 11:32:44]

ㅜㅜ 정말 최고의 답변입니당 .. 도움이 되었어요. 책으로 열심히 공부해보겠습니당


by 마농 [2018.07.24 17:26:52]

1. Exists 구문은
  - 큰 무리가 없어 보입니다.
  - 단, 조건절 인덱스는 필수입니다.
  - 구문도 딱히 복잡해 보이지는 않네요.
2. 쿼리 분리하여 두번 수행은
  - DB Call 을 두번하는 부하가 있겠네요.
  - 자주 사용되거나, 반복문 안에서 처리되는 구문이라면 문제의 소지가 있구요.
  - 그렇지 않은 경우라면? 큰 무리가 없어 보입니다.
3. PK 는
  - 단일항목 뿐 아니라 복합(결합)키도 가능합니다.
  - PK 항목 추가는 불가합니다. 삭제 후 재생성 해야 합니다.


by 음미 [2018.07.25 11:33:31]

ㅜㅜ 좋은 답변 감사드립니당!! INDEX 꼭 넣어야 겠네요

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입