2.7-3 Combining Columns
use-the-index-luke 저자 Markus Winand
---------------------------------------------
Markus Winand는 SQL에 대한 통찰력을 제공하고 다양한 시스템이 SQL을 지원하는 방법을 modern-sql.com 에서 보여줍니다. 이전에 그는 use-the-index-luke.com 을 만들었는데, 지금도 활발하게 유지되고 있습니다. Markus는 winand.at 를 통해 강사, 연사 및 컨설턴트로 고용될 수 있습니다.
---------------------------------------------
You can upload a Korean translation of use-the-index-luke.com on your blog
Thank you from the bottom of my heart to author Makus Winand for allowing me.
These are translations that I use for studying by using a papago (google translate)
The translations may not be correct or there may be a typo.
I'd appreciate it if you could point it out in the comments.
---------------------------------------------
---------------------------------------------
use-the-index-luke.com 의 한글번역본을 블로그에 업로드 해도 된다고
허락해주신 Makus Winand 저자님께 진심으로 감사합니다.
이 번역본들은 제가 공부용도로 번역기(papago, google transrate)를 돌려서
번역한 내용들이라 맞지 않거나, 오타가 있을수 있습니다.
댓글로 지적해주시면 감사하겠습니다.
---------------------------------------------
https://use-the-index-luke.com/sql/where-clause/obfuscation/concatenation
ㄴ 열 결합
이 섹션에서는 연결된 인덱스에 영향을 미치는 일반적인 난독화에 대해 설명합니다.
첫 번째 예는 날짜와 시간 유형에 대한 것이지만 그 반대입니다.
다음 MySQL 쿼리는 날짜와 시간 열을 결합하여 둘 다에 범위 필터를 적용합니다.
----------------------------------------------------------
SELECT ...
FROM ...
WHERE ADDTIME(date_column, time_column)
> DATE_ADD(now(), INTERVAL -1 DAY)
----------------------------------------------------------
지난 24 시간 동안의 모든 레코드가 선택됩니다.
검색이 인덱싱된 열이 아니라 파생된 데이터에 대해 수행되기 때문에 쿼리가(DATE_COLUMN, TIME_COLUMN)에 연결된 인덱스를 제대로 사용할 수 없습니다.
날짜 및 시간 구성 요소를 모두 포함하는 데이터 유형(예: MySQL DATETIME)을 사용하여 이 문제를 방지할 수 있습니다. 그런 다음 함수 호출 없이 이 열을 사용할 수 있습니다.
----------------------------------------------------------
SELECT ...
FROM ...
WHERE datetime_column
> DATE_ADD(now(), INTERVAL -1 DAY)
----------------------------------------------------------
안타깝게도 이 문제에 직면했을 때 테이블 변경할 수 없는 경우가 많습니다.
데이터베이스가 지원하는 경우 다음 옵션은 Function Based INDEX입니다. 이전에 설명한 모든 단점이 있습니다. MySQL을 사용할 때 Function Based INDEX는 옵션이 아닙니다.
데이터베이스가 DATA_COLUMN,TIME_COLUMN의 연결된 인덱스와 access predicate(적어도 부분적으로)를 사용할 수 있도록 쿼리를 작성할 수 있습니다.
이를 위해 DATE_COLUMN에 추가 조건을 추가합니다.
----------------------------------------------------------
WHERE ADDTIME(date_column, time_column)
> DATE_ADD(now(), INTERVAL -1 DAY)
AND date_column
>= DATE(DATE_ADD(now(), INTERVAL -1 DAY))
----------------------------------------------------------
새 조건은 절대적으로 중복되지만 DATE_COLUMN의
스트레이트 필터로 access predicate를 사용할 수 있습니다. 이 기법은 완벽하지는 않지만 대개 충분히 근사합니다.
----------------------------------------------------------
Tip
범위 조건이 여러 열을 결합하는 경우 가장 유의한 열에 중복 조건을 사용합니다.
PostgrSQL 이면, 행 값 구문을 사용하는 것이 좋습니다.
----------------------------------------------------------
날짜와 시간을 텍스트열에 저장할 때도
이 방법을 사용할 수 있지만, ISO 8601(YYYY-MM-DD HH:MM:SS)에서 제안한 것처럼 사전 정렬시 시간순으로 정렬되는 날짜와 시간 형식을 사용해야 합니다.
다음 예제에서는 Oracle 데이터베이스의 TO_CHAR 함수를 사용합니다:
----------------------------------------------------------
SELECT ...
FROM ...
WHERE date_string || time_string
> TO_CHAR(sysdate - 1, 'YYYY-MM-DD HH24:MI:SS')
AND date_string
>= TO_CHAR(sysdate - 1, 'YYYY-MM-DD')
----------------------------------------------------------
“Paging Through Results” 섹션에서 다시 여러열에 범위 조건을 적용하는 문제에 대해 설명합니다.
또한 이를 완화하기 위해 동일한 접근 방법을 사용할 것 입니다.
경우에 따라 반대의 경우가 발생하여 조건을 의도적으로 난독화하여 더 이상 access predicate로 사용할 수 없게 하려는 경우가 있습니다 바인딩 매개 변수가 LIKE 조건에 미치는 영향에 대해 논의할 때 이미 그 문제를 살펴보았습니다. 다음 예시를 생각해 보십시오.
----------------------------------------------------------
SELECT last_name, first_name, employee_id
FROM employees
WHERE subsidiary_id = ?
AND last_name LIKE ?
----------------------------------------------------------
SUBSIDIARY_ID에 인덱스가 있고 LAST_NAME에 인덱스가 있다고 가정하면 이 쿼리에 대해 어떤 것이 더 나은가요?
검색어에서 와일드카드의 위치를 모르면 적격한 답변을 제공할 수 없습니다.
optimizer 은 "계속"하는 것 외에는 다른 선택의 여지가 없습니다. 항상 선행 와일드카드가 있다는 것을 알고 있는 경우, LIKE 조건을 의도적으로 난독화하여 optimizer 가 더 이상 LAST_NAME의의 인덱스를 고려할 수 없도록 할 수 있습니다.
----------------------------------------------------------
SELECT last_name, first_name, employee_id
FROM employees
WHERE subsidiary_id = ?
AND last_name || '' LIKE ?
----------------------------------------------------------
LAST_NAME 열에 빈 문자열을 추가하기에 충분합니다.
그러나 이것은 최후의 수단입니다. 꼭 필요할때만 하세요.