Oracle, MySQL, Goldilocks 등을 활용하여 개발하시는 분들의 쿼리를 보다보면, 쿼리문에 WHERE 1 = 1 을 쓰는 모습을 종종 볼 수 있었습니다.
아무래도 소스상의 가독성 때문에 이렇게 사용하는 분들이 많이 있을텐데요.
WHERE 1 = 1 의 구문이 없는 소스의 경우와 있는 소스를 보면 가독성에 차이가 있습니다.
mozi.append(" SELECT ID, AGE "); mozi.append(" FROM MOZI "); mozi.append(" WHERE "); if ( ID != null ){ mozi.append(" ID = 91 "); } if ( AGE != null) { if ( ID != null ) { mozi.append(" AND AGE = 28"); }else{ mozi.append(" AGE = 28 "); } }
mozi.append(" SELECT ID, AGE "); mozi.append(" FROM MOZI "); mozi.append(" WHERE 1 = 1 "); if ( ID != null ){ mozi.append(" AND ID = 91 "); } if ( AGE != null ){ mozi.append(" AND AGE = 28 "); }
그렇다면, INDEX FILTER 는 탈까요?
다른 데이터베이스는 다시 확인해봐야지만 Goldilocks 에서는 Index 를 타는걸로 확인되었습니다.
gSQL> EXPLAIN PLAN 2 SELECT ID, AGE FROM MOZI WHERE 1 = 1 AND ID = 91 AND AGE = 28; >>> start print plan < Execution Plan > ================================================================================================== | IDX | NODE DESCRIPTION | ROWS | -------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | 1 | FILTER | 1 | | 2 | INDEX ACCESS ("MOZI", "MOZI_IDX") [CLONED] | ( 1) 1 | ================================================================================================== 1 - READ COLUMNS : MOZI.ID, MOZI.AGE NODE FILTER : 1 = 1 2 - READ INDEX COLUMNS : ID READ TABLE COLUMNS : AGE MIN RANGE : ID = 91 MAX RANGE : ID = 91 PHYSICAL TABLE FILTER : AGE = 28 <<< end print plan
이것만 놓고보면 WHERE 1 = 1 은 성능에서 부족함도 없으며, 소스에서 정말 좋은 가독성을 제공할련지도 모르겠습니다.
그렇지만 이 쿼리는 너무 위험한 데요.
만약 어떤 이유로든 ID 와 AGE 의 인자값이 NULL 이 들어왔다고 가정해봅니다.
조건절의 append 는 수행되지 않고, 이로 인해 SELECT ID, AGE FROM MOZI WHERE 1 = 1 이라는 전체 데이터를 조회하는 쿼리가 되버립니다.
그나마 SELECT 라서 다행이라지만(물론, 이로인해 전체 개인정보가 유출되었다면 심각합니다.) DELETE 라면 어떻게될까요?
DELETE FROM MOZI WHERE 1 = 1 AND ID = 91 AND AGE = 28 쿼리는
DELETE FROM MOZI WHERE 1 = 1 이라는 전체 데이터를 삭제하는 무시무시한 쿼리로 변하게 됩니다.
차라리 DELETE FROM MOZI WHERE ; 구문으로 인해 문법오류를 발생하는 편이 더 좋지않을까요?
물론 개발자 분들이 NULL 예외처리를 하겠지만, 실수와 잠재적 위험성은 언제나 도사리고 있습니다. 그것도 심각한 상황으로요.
과연 쓰는게 맞을지는 여러분들의 판단에 맡기도록 하겠습니다.
'Database > DBA 의 개인생각' 카테고리의 다른 글
[DBA] 트리거가 성능에 미치는 악영향에 대해서 (0) | 2019.08.07 |
---|---|
[DBA] 게시판 페이징 처리하는 방법 (Scan VS Seek) (0) | 2019.05.02 |
[DBA] COUNT(*) 안쓰고 테이블 총 레코드 조회하는 법 생각해보기 (0) | 2019.02.12 |
[DBA] DBA 란, DBA 가 하는일 알아보기 (0) | 2018.11.25 |
[DBA] 데이터타입 CHAR 와 VARCHAR 중 어느것을 써야할까? (1) | 2018.11.08 |