EXPLAIN SELECT 에서 이해가 안가는 부분이 있어요 ㅜㅜ 0 4 1,187

by 음미 [SQL Query] [2018.08.13 20:35:58]


안녕하세요. users_day에서 user_id랑 written_date를 UNIQUE키 한 묶음으로 사용하고있는데요. 

첫번째) 두개의 쿼리를 EXPLAIN 해보니 filtered 값이 달라서 질문드려요. 계산 상으로는 똑같은 쿼리인데 (1) 쿼리는 33.33 filtered 값이 나오고요 (2)는 100이 나오는데 어떤 차이로 생기는 걸까요? (3)번처럼 뒤에 DATE를 붙이면 filtered 값이 다시 100이 되기는 합니다 ㅜㅜ written_date도 DATE 타입이라 굳이 DATE로 명시하지 않아도 비교하는데 문제가 없을 것 같은데 무슨 차이가 있는 걸까요?

두번째) user_id=24인 row가 실제로 232개이고, user_id=24이고 7월 23일 이전인 row가 159개 인데요.
EXPLAIN 하면 rows 컬럼에 (1) 결과가 159 rows이고 (2),(3) 에서는 232rows가 나옵니다.  공식 document에서 “””rows shows the estimated number of rows examined and rows × filtered shows the number of rows that will be joined with the following table. ””” 라고 나오는데요. 그렇다면 (1)의 결과에서 159*0.33(filtered값) 하면 53밖에 안나오는데 어떻게 SELECT 한 결과 row가 159개가 될 수있나요? 나머지 106개의 데이터는 어디 테이블에서 나오는건가요? 제가 잘못 이해한 것 같은데 알려주시면 감사하겠습니다ㅜㅜ
https://dev.mysql.com/doc/refman/8.0/en/explain-output.html#explain_filtered

(1)EXPLAIN SELECT * FROM users_day WHERE user_id=24 AND '2018-07-23'>=written_date;



(2)EXPLAIN SELECT * FROM users_day WHERE user_id=24 AND DATEDIFF('2018-07-23',written_date)>=0;



(3)EXPLAIN SELECT * FROM users_day WHERE user_id=24 AND '2018-07-23'>=DATE(written_date);

 

 

by 마농 [2018.08.17 14:24:40]

1. 인덱스 컬럼을 가공하여 비교하는 것과 그대로 비교하는 것은 차이가 있습니다.
  - (1)번은 가공 없이 비교하므로 인덱스를 그대로 잘 활용합니다.
  - (2),(3) 번은 written_date 항목에 함수를 적용하여 가공하므로 비효율입니다.
  - 인덱스 조건을 그대로 엑세스 조건으로 이용하는게 아니라 필터조건으로밖에 사용하지 못합니다.
2. 조건에 따른 결과 차이
  - 날짜가 일자까지만 있는지? 시분초까지도 포함되고 있는지에 따라 결과가 달라집니다.
  - (1)번은 written_date <= '2018-07-23 00:00:00'
  - (2)번은 written_date <= '2018-07-23 23:59:59'
  - (3)번도 written_date <= '2018-07-23 23:59:59'
3. 실행계획 건수가 실제 결과 건수와 딱 맞아 떨어지지는 않습니다.


by 음미 [2018.08.29 14:45:02]

헉! 답변이 없는 줄 알고 확인을 안했었는데 답변 정말 감사합니다 ㅜㅜ 그런데 (1)번이 인덱스를 더 잘 활용한다고 생각했는데 filtered 값은 33.33으로 왜 더 낮게 나올까요? 저는 100이 나오면 더 성능이 좋은 것으로 생각했었는데요.(틀릴수도 있다는 생각이 드네요). 원래 filtered 100이 더 성능이 좋다는게 맞다면 filtered 값보다는 함수를 가공했는지 여부가 더 중요한건가요?


by 마농 [2018.08.29 16:09:31]

filtered 는 읽고 나서 버려진 비율 아닌가요?
  1)번의 경우 적게 읽고 적게 버린거구요, 필요한 만큼만 읽음.
  2)번의 경우 많이 읽고 많이 버린거구요, 불필요하게 많이 읽음.
수치만 보고 100% 판단하시면 안됩니다.
  수치는 예측입니다. 딱 맞아 떨어지지 않을 것입니다.
  논리적인 실행 과정을 생각하고 비효율은 없는지 확인해야 합니다.
쿼리 성능 비교시
  1번과 2,3번을 비교하는 것은 무의미합니다.
  결과가 다르기 때문에 성능비교 자체가 성립이 안됩니다.
  성능보다 중요한 것은 정확성입니다.
  아우리 빨리 조회되는 자료라도 부정확하다면 소용 없죠.


by 음미 [2018.08.31 11:56:19]

ㅜㅜ 감사합니다, 새겨듣겠습니다!

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