ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Real MySQL [7-3] 쿼리 작성 및 최적화 - MySQL 연산자
    MySQL 2017. 1. 2. 21:28



    본 게시물의 내용과 이미지는 도서 Real MySQL의 내용을 재구성하여 작성되었습니다. 저자, 출판사에 의해 저작권 문제 발생시 게시물이 비공개 될 수 있음을 알립니다. 




    MySQL 연산자


    동등(Equal) 비교( =, <=>)


    동등 비교는 다른 DBMS와 마찬가지로 "=" 기호를 사용해 비교를 수행하면 된다. MySQL은 동등 비교를 위해 "<=>" 연산자도 제공한다. "<=>" 연산자는 "=" 연산자와 같으며, 부가적으로 NULL 값에 대한 비교까지 수행한다. 




    위 예제와 같이 NULL은  "IS NULL" 연산자 이외에는 비교할 방법이 없다. 하지만 Null-Safe 비교연산자를 이용해 비교한 결과를 보면 양쪽 비교 대상 모두 NULL이라면 TRUE를 반환하고, 한쪽만 NULL이라면 FALSE를 반환한다. 즉 "<=>" 연산자는  NULL을 하나의 값으로 인식하고 비교하는 방법이라고 볼 수 있다.



    부정(Not-Equal) 비교 ( <>, != )


    "같지 않다" 비교를 위한 연산자는 "<>"를 일반적으로 많이 사용한다. "!="도 Not-Equal 연산자로 사용할 수 있다. 어느 쪽을 사용하든 특별히 문제가 되지는 않지만 혼용되면 가독성이 떨어지므로 통일해서 사용하는 방법을 권장한다.



    NOT 연산자 (!)


    TRUE 또는 FALSE 연산의 결과를 반대로 만드는 연산자로 "NOT" 을 사용한다. 또한 "!" 연산자를 같은 목적으로 사용할 수 있다. 부정 연산자는 숫자나 문자열 표현식에서도 사용할 수 있지만 부정의 결과 값을 정확히 예측할 수 없는 경우에는 사용을 자제하는 것이 좋다.



    AND(&&) 와 OR(||) 연산자 


    일반적으로 DBMS에서는 불리언 표현식의 결과를 결합하기 위해 AND나 OR을 사용한다. MySQL에서는 AND와 OR뿐 아니라 "&&"와 "||"의 사용도 허용하고 있다. "&&"는 AND 연산자와 같으며, "||"는 OR 연산자와 같다. 오라클에서는 "||"가 불리언 표현식의 결합 연산자가 아니라 문자열을 결합하는 연산자로 사용된다. 만약 오라클에서 운영되던 애플리케이션을  MySQL로 이관하거나 문자열 결합 연산에 "||"를 사용하고자 하는 경우 sql_mode 시스템 변수 값의 PIPE_AS_CONCAT를 설정하면 된다. 


    SQL의 가독성을 높이기 위해 다른 용도로 사용될 수 있는 "&&" 연산자와 "||" 연산자는 사용을 자제하는 것이 좋다. 




    나누기(/, DIV) 와 나머지(%, MOD) 연산자


    나누기 연산자는 일반적으로 "/" 연산자를 사용한다. 나눈 몫의 정수 부분만 가져오려면 DIV 연산자를 사용하고 나머지만 가져오는 연산자는 "%" 또는 MOD 연산자(함수)를 사용한다.



    REGEXP 연산자


    문자열 값이 어떤 패턴을 만족하는지 확인하는 연산자이며, RLIKE는 REGEXP와 똑같은 비교를 수행하는 연산자다. RLIKE는 가끔 문자열 값의 오른쪽 일치용 LIKE 연산자(Right LIKE)로 혼동할 때가 있는데  RLIKE는 정규 표현식 비교 연산자라는 점을 기억하자. 아래의 예제와 같이 REGEXP 연산자의 좌측에 비교 대상 문자열 값 또는 문자열 칼럼, 그리고 우측에는 검증하고자 하는 정규 표현식을 사용하면 된다. 


    다음 예제는 "abc"라는 문자열 값이 'x', 'y', 'z' 문자로 시작하는지 검증하는 표현식의 예이다.


    mysql> SELECT 'abc' REGEXP '^[x-z]';


    REGEXP 연산자 정규 표현식은 POSIX 표준으로 구현되 있어서 POSIX 정규 표현식에 사용하는 패턴 키워드를 그대로 사용할 수 있다. 아래는 대표적으로 많이 사용되는 심벌 몇 개를 소개한다.



    ^

    문자열의 시작을 표시, 정규 표현식은 그 표현식에 일치하는 부분이 문자열의 시작이나 중간 또는 끝 부분 어디에 나타나든 관계없지만 "^"심벌을 표현식의 앞쪽에 넣어 주면 반드시 일치하는 부분이 문자열의 제일 앞쪽에 있어야 함을 의미한다. 


    $

    문자열의 끝을 표시, "^"와는 반대로 표현식의 끝 부분에 "$"를 넣어 주면 반드시 일치하는 부분이 문자열의 제일 끝에 있어야 함을 의미한다. 


    []

    문자 그룹을 표시, [xyz] 또는 [x-z]라고 표현하면 'x' ,'y', 또는 'z' 문자 중 하나인지 확인하는 것이 된다. 대괄호는 문자열이 아니라 문자 하나와 일치하는지를 확인하는 것이다. 


    () 

    문자열 그룹을 표시, (xzy)라고 표현하면 세 문자 중 한 문자가 있는지 체크하는 것이 아니라 반드시 'xzy'가 모두 있는지 확인하는 것이다. 


    |

    "|"로 연결된 문자열 중 하나인지 확인한다 abc|xyz라고 표현하면 "abc"이거나 "xyz"인지 확인하는 것이다.


    .

    어떠한 문자든지 1개의 문자를 표시하며, 정규 표현식으로 "..." 이라고 표현했다면 3개의 문자(실제 문자의 값에 관계없이)로 구성된 문자열을 찾는 것이다.


    *

    이 기호 앞의 표시된 정규 표현식은 0 또는 1번 이상 반복될 수 있다는 표시다.


    +

    이 기호 앞에 표시된 정규 표현식이 1번 이상 반복될 수 있다는 표시다.


    ?

    이 기호 앞에 표시된 정규 표현식이 0번 또는 1번만 올 수 있다는 표시다. 


    전화번호나 이메일 주소처럼 특정한 형태를 갖춰야하는 문자열 검증 예시이다.


    [0-9]*

    '0' ~ '9' 까지의 숫자만 0 또는 1번 이상 반복되는 문자열을 위한 정규 표현


    [a-z]*

    'a' ~ 'z' 까지의 소문자 알파뱃만 0 또는 1번 이상 반복되는 문자열을 위한 정규 표현 


    [a-zA-Z]*

    'a' ~ 'z' 까지 그리고 'A' ~ 'Z' 까지 대소문자  0 또는 1번 이상 반복되는 문자열을 위한 정규 표현 


    [a-zA-Z0-9]*

    영문 대소문자와 숫자만으로 구성된 문자열에 대한 정규 표현 


    ^Tear

    Tear 문자열로 시작하는 정규 표현


    Tear$

    Tear 문자열로 끝나는 정규 표현


    ^Tear$

    Tear와 같은 문자열에 대한 정규 표현, 이 경우는 'T'로 시작하고 연속해서 ear이 나타나야 하며 그 뒤에 아무런 문자가 없어야 한다. 


    REGEXP 조건의 비교는 인덱스 레인지 스캔을 사용할 수 없다. 따라서 WHERE 조건절에 REGEXP 연산자를 사용한 조건을 단독으로 사용하는 것은 성능상 좋지 않다. 가능하다면 범위를 줄일 수 있는 조건과 함께 REGEXP 연산자를 사용하길 권장한다. 



    LIKE 연산자


    REGEXP 연산자보다는 훨씬 단순한 문자열 패턴 비교 연산자 이지만 DBMS 에서는 LIKE 연산자를 더 많이 사용한다. REGEXP 연산자는 인덱스를 전혀 사용하지 못한다는 단점이 있지만, LIKE 연산자는 인덱스를 이용해 처리할 수도 있다. LIKE 연산자는 정규 표현식을 검사하는 것이 아니라 어떤 상수 문자열이 있는지 없는지 정도를 판단하는 연산자 이다. 


    mysql> SELECT 'abcdef' LIKE '%EF'; // 1


    LIKE 에서 사용가능한 와일드카드 문자는 "%"와 "_"가 전부다. LIKE는 항상 비교 대상 문자열의 처음부터 끝까지 일치하는 경우에만 TRUE를 반환한다.


    0 또는 1개 이상의 모든 문자에 일치(문자의 내용과 관계없이)


    _

    정확히 1개의 문자에 일치(문자의 내용과 관계없이)


    만약 와일드카드 문자인 '%'나 '_' 문자 자체를 비교한다면 ESCAPE 절을 LIKE 조건 뒤에 추가해 이스케이프 문자를 설정할 수 있다. 


    mysql> SELECT ' a%' LIKE 'a/%' ESCAPE '/';    // 1


    LIKE 연산자는 와일드카드 문자인 (%, _)가 검색어 뒤쪽에 있다면 인덱스 레인지 스캔을 사용할 수 있지만 와일드카드가 검색어의 앞쪽에 있다면 인덱스 레인지 스캔을 사용할 수 없으므로 주의해서 사용해야 한다. 


    EXPLAIN 

    SELECT(*)

    FROM employees WHERE first_name LIKE 'Christ%';





    반대로 와일드카드가 검색어 앞쪽에 있으면 인덱스의 Left-most 특성으로 인해 레인지 스캔을 사용하지 못하고 인덱스를 처음부터 끝까지 읽는 인덱스 풀 스캔 방식으로 쿼리가 처리된다.


    EXPLAIN

    SELECT COUNT(*)

    FROM employees WHERE first_name LIKE '%rstian';




Designed by Tistory.