Press "Enter" to skip to content

[태그:] MySQL

Mysql 인덱스(index) 와 컬럼 중복도(Cardinality)의 관계 정리

중복도가 낮으면 카디널리티(Cardinality)가 높다고 표현하고, 중복도가 높으면 카디널리티가 낮다고 표현합니다.

인덱스와의 관계는 중복도가 낮으면 효율이 높아지고, 중복도가 높으면 효율이 낮아집니다.

중복도가 낮다는 것은 특정 컬럼의 데이터가 각기 다른 값이 들어간다는 뜻입니다.

프라이머리 키(pk)나, 주민번호 같은 유일값일 수도 있고 풀네임 같이 중복은 있지만 그리 중복이 많지 않은 데이터를 가지고 있는 컬럼을 의미합니다.

반면 중복도가 높다는 것은 같은 값이 많이 들어가는 컬럼을 의미합니다. 예를 들자면 성별 컬럼 정도 되겠습니다.

1000만건의 데이터가 들어가 있어도 남자, 여자, 기타 정도 들어갈 테니깐 중복된 데이터가 겁나게 많겠죠.

인덱스를 설정할때, pk 같이 중복도가 높은 컬럼에는 효율이 높지만, 성별같이 중복도가 높은 컬럼에 인덱스를 걸면 도리어 row가 늘어나면 늘어날 수록 효율성을 떨어뜨립니다.(업데이트, 인서트시 성능이 확!!! 떨어질 수 있습니다.)

따라서 중복도가 높은 컬럼에만 인덱스를 설정할 것을 권장합니다.

중복도를 조회하는 방법은 아래 쿼리를 사용합니다.

show index from 테이블이름;

조회되는 내용중에 Cardinality 값이 작은 column에는 인덱스를 걸지 마세요.

A테이블에 있고, B테이블에 없는 데이터 조회

SELECT A.id, B.name

FROM A

LEFT OUTER JOIN B

ON A.ID=B.A_ID

WHERE B.job IS NULL

B테이블의 Record 갯수가 많을 경우 시간이 오래 걸려 성능에 악영향을 끼친다.

예를들어 A 테이블 직원row가 2000명, B테이블 담당업무row가 30만개 라면 수분에서 수십분… 수시간이나 수일이 걸릴 수도 있다.

급한대로 일단 UI에서 조회항목에 대한 제한을 걸어 B 테이블의 조회 건수를 대폭 줄여주자

[PHP] mysql update 된 row 수 체크하기

<?php
$mysql = new mysqli("localhost","username","password","use_db");

if($mysql->connect_errno)
{
  echo "MySQL 접속 실패 : ".$mysql->connect_error;
  exit();
}

// 업데이트 처리
$mysql->query("UPDATE usertable SET name = 'myName' where id = 100");
echo "적용된 row 수: ".$mysql->affected_rows;

$mysqli->close();
?>

SELECT 일때도 동일하게 사용할 수 있습니다.

다만, query() 의 리턴 변수에서 체크하는 것이 아니라 mysqli 인스턴스로 체크합니다.