• 검색기능 구현 MySQL의 LIKE 대 REGEXP(그리고 mybatis를 곁들인..)

    2024. 11. 16.

    by. Sohyun

    REGEXP 정규식으로 검사하는 기능
    - 정규식의 검색을 이용할때 절대 사용자에게 정규식 기능을 제공해선 안된다. 

    1) 사용자 입력으로 정규표현식 검색이 되는가?(SQL 인젝션 공격 위험)
    mybatis의 #{} 문법으로 파라미터를 바인딩이 것의 가장 큰 장점은 SQL 인젝션 공격을 방지한다는 것
    사용자 입력값이 직접 SQL 문에 삽입되지 않고, 데이터로서 처리되기 때문에 악의적인 SQL 코드 실행을 막을 수 있음
    ${}는 문자열 치환 방식으로 작동하여 SQL 인젝션에 취약할 수 있으므로 동적 테이블명이나 컬럼명과 같은 특수한 경우를 제외하고는 #{}를 사용하는 것이 좋다.

    그런데 mybatis 문법을 사용하면 정규식의 장점을 사용하지 못하는거 아닌가?
    대부분의 경우 LIKE가 REGEXP보다 성능이 더 좋음
    LIKE는 인덱스를 활용할 수 있지만, REGEXP는 일반적으로 인덱스를 활용하지 못함

    2) 그럼에도 REGEXP를 사용하는 이유?
    복잡한 패턴 매칭: 여러 조건을 동시에 검색해야 하는 경우
    여러 LIKE 조건을 OR로 연결하는 대신 하나의 REGEXP로 표현할 수 있어, 일부 상황에서는 REGEXP가 더 효율적

    결론
    간단 단일 조건: LIKE가 더 빠릅니다
    복잡한 다중 조건: REGEXP가 더 빠릅니다

    -------------
    이해하기 쉽게 알려주신 내용이 있어 참고했다.
    https://stackoverflow.com/questions/16646686/mysql-regexp-vs-like/56090836

    단일 조건
    SELECT * FROM comments WHERE text LIKE '%\\\\n%'; 🚀 Faster
    SELECT * FROM comments WHERE text REGEXP '\\\\n'; 🐢 Slower
    다중 조건
    SELECT * FROM comments
    WHERE text LIKE '%\\\\r\\\n%'
    OR text LIKE '%\\\\n%'
    OR text LIKE '%\\\\r%'; 🐢 Slower

    SELECT * FROM comments
    WHERE text REGEXP '((\\\\r\\\\n)|(\\\\(n|r)))'; 🚀 Faster
    ---------------------
    나는 
    ++++++++++++
    REGEXP_REPLACE(컬럼명, '<[^>]*>', '') 
    태그 없애고 검색하고 싶을 때 사용

    like에서 인덱스를 활용하는 방법?
    Full-Text Index를 사용하면  대량의 텍스트 필드에서 빠르게 검색할 수 있다고 함 
    일반 인덱스 사용
    예를 들어 키워드 검색시 조건에 
    REGEXP_REPLACE(COLNAME, '<[^>]*>', '') LIKE #{keyword}를 사용할 때

    REGEXP_REPLACE(COLNAME, '<[^>]*>', '') 가 된 컬럼 추가후 이를 인덱스 추가한 후
     LIKE #{keyword} 만 쓰면 인덱스를 사용할 수 있다는 것 같음

    그런데 이 방법을 사용하면 저장공간이 많이 필요하지 않을까?

    데이터베이스에 종속적이지 않으면서도 저장 공간을 덜 사용하려면, FULLTEXT INDEX나 검색 엔진 연동 방안을 고려하는 것이 좋다고 함

    댓글