MySQL 백만 급 데이터 의 4 가지 조회 최적화 방식

1.limit 이 뒤로 갈수 록 느 려 지 는 이유
우리 가 limit 을 사용 하여 데 이 터 를 페이지 별로 조작 할 때 앞의 몇 페이지 를 볼 때 속도 가 매우 빠르다 는 것 을 발견 할 수 있다.예 를 들 어 limit 200,25,순간 에 나 왔 다.하지만 뒤로 갈수 록 속도 가 느 려 집 니 다.특히 백만 개가 지나 면 걸 리 지 않 습 니 다.그럼 이 원 리 는 무엇 입 니까?먼저 우리 가 페이지 를 뒤로 넘 겼 을 때 조회 한 sql 이 어떤 지 보 세 요.

select * from t_name where c_name1='xxx' order by c_name2 limit 2000000,25;
이런 조회 가 느 린 것 은 사실 limit 뒤의 오프셋 이 너무 많아 서 생 긴 것 이다.예 를 들 어 위의 limit 20000,25 와 같이 이것 은 데이터베이스 에서 2000025 개의 데 이 터 를 스 캔 한 다음 에 앞의 20000000 개의 데 이 터 를 버 리 고 나머지 25 개의 데 이 터 를 사용자 에 게 되 돌려 주 는 것 과 같다.이런 취 법 은 현저히 불합리 하 다.

백만 데이터 시 뮬 레이 션
1.직원 표 와 부서 표를 만 들 고 저장 과정 을 작성 하여 데 이 터 를 삽입 합 니 다.

/*   ,        */
drop table if EXISTS dep;
create table dep(
    id int unsigned primary key auto_increment,
    depno mediumint unsigned not null default 0,
    depname varchar(20) not null default "",
    memo varchar(200) not null default ""
);

/*   ,       */
drop table if EXISTS emp;
create table emp(
    id int unsigned primary key auto_increment,
    empno mediumint unsigned not null default 0,
    empname varchar(20) not null default "",
    job varchar(9) not null default "",
    mgr mediumint unsigned not null default 0,
    hiredate datetime not null,
    sal decimal(7,2) not null,
    comn decimal(7,2) not null,
    depno mediumint unsigned not null default 0
);
/*           */
DELIMITER $
drop FUNCTION if EXISTS rand_string;
CREATE FUNCTION rand_string(n INT) RETURNS VARCHAR(255)
BEGIN
    DECLARE chars_str VARCHAR(100) DEFAULT 'abcdefghijklmlopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    DECLARE return_str VARCHAR(255) DEFAULT '';
    DECLARE i INT DEFAULT 0;
    WHILE i < n DO
    SET return_str = CONCAT(return_str,SUBSTRING(chars_str,FLOOR(1+RAND()*52),1));
    SET i = i+1;
    END WHILE;
    RETURN return_str;
END $
DELIMITER;


/*           */
DELIMITER $
drop FUNCTION if EXISTS rand_num;
CREATE FUNCTION rand_num() RETURNS INT(5)
BEGIN
    DECLARE i INT DEFAULT 0;
    SET i = FLOOR(100+RAND()*10);
    RETURN i;
END $
DELIMITER;
/*      : emp      */
DELIMITER $
drop PROCEDURE if EXISTS insert_emp;
CREATE PROCEDURE insert_emp(IN START INT(10),IN max_num INT(10))
BEGIN
    DECLARE i INT DEFAULT 0;
    /*set autocommit =0  autocommit   0,       */
    SET autocommit = 0;
    REPEAT
    SET i = i + 1;
    INSERT INTO emp(empno,empname,job,mgr,hiredate,sal,comn,depno) VALUES ((START+i),rand_string(6),'SALEMAN',0001,now(),2000,400,rand_num());
    UNTIL i = max_num
    END REPEAT;
    COMMIT;
END $
DELIMITER;

/*      : dep      */
DELIMITER $
drop PROCEDURE if EXISTS insert_dept;
CREATE PROCEDURE insert_dept(IN START INT(10),IN max_num INT(10))
BEGIN
    DECLARE i INT DEFAULT 0;
    SET autocommit = 0;
    REPEAT
    SET i = i+1;
    INSERT  INTO dep( depno,depname,memo) VALUES((START+i),rand_string(10),rand_string(8));
    UNTIL i = max_num
    END REPEAT;
    COMMIT;
END $
DELIMITER;
2.저장 프로시저 실행

/*  120   */
call insert_dept(1,120);
/*  500W   */
call insert_emp(0,5000000);
500 만 개의 데 이 터 를 삽입 하 는 것 은 느 릴 수 있 습 니 다.
3.4 가지 조회 방식
1.일반 제한 페이지

/*    100, 25*/
SELECT a.empno,a.empname,a.job,a.sal,b.depno,b.depname
from emp a left join dep b on a.depno = b.depno order by a.id desc limit 100,25;
/*    4800000, 25*/
SELECT a.empno,a.empname,a.job,a.sal,b.depno,b.depname
from emp a left join dep b on a.depno = b.depno order by a.id desc limit 4800000,25; 
실행 결과

[SQL]
SELECT a.empno,a.empname,a.job,a.sal,b.depno,b.depname
from emp a left join dep b on a.depno = b.depno order by a.id desc limit 100,25;
     : 0
  : 0.001s
[SQL]
SELECT a.empno,a.empname,a.job,a.sal,b.depno,b.depname
from emp a left join dep b on a.depno = b.depno order by a.id desc limit 4800000,25;
     : 0
  : 12.275s
뒤로 갈수 록 조회 효율 이 느리다
2.색인 덮어 쓰기+하위 검색 최적화 사용
홈 키 id 가 있 고 위 에 색인 을 만 들 었 기 때문에 색인 트 리 에서 시작 위치의 id 값 을 찾 은 다음 에 찾 은 id 값 에 따라 줄 데 이 터 를 조회 할 수 있 습 니 다.

/*       100     id,         25*/
SELECT a.empno,a.empname,a.job,a.sal,b.depno,b.depname
from emp a left join dep b on a.depno = b.depno
where a.id >= (select id from emp order by id limit 100,1)
order by a.id limit 25;

/*       4800000     id,         25*/
SELECT a.empno,a.empname,a.job,a.sal,b.depno,b.depname
from emp a left join dep b on a.depno = b.depno
where a.id >= (select id from emp order by id limit 4800000,1)
order by a.id limit 25;
실행 결과

[SQL]
SELECT a.empno,a.empname,a.job,a.sal,b.depno,b.depname
from emp a left join dep b on a.depno = b.depno
where a.id >= (select id from emp order by id limit 100,1)
order by a.id limit 25;
     : 0
  : 0.106s

[SQL]
SELECT a.empno,a.empname,a.job,a.sal,b.depno,b.depname
from emp a left join dep b on a.depno = b.depno
where a.id >= (select id from emp order by id limit 4800000,1)
order by a.id limit 25;
     : 0
  : 1.541s
3.시작 위치 재 정의
홈 키 에 적용 되 는 것 은 홈 키 를 추가 하 는 표 입 니 다.

/*                id 100,       100, 101     */
SELECT a.id,a.empno,a.empname,a.job,a.sal,b.depno,b.depname
from emp a left join dep b on a.depno = b.depno
where a.id > 100 order by a.id limit 25;

/*                id 4800000,       4800000, 4800001     */
SELECT a.id,a.empno,a.empname,a.job,a.sal,b.depno,b.depname
from emp a left join dep b on a.depno = b.depno
where a.id > 4800000
order by a.id limit 25;

[SQL]
SELECT a.id,a.empno,a.empname,a.job,a.sal,b.depno,b.depname
from emp a left join dep b on a.depno = b.depno
where a.id > 100 order by a.id limit 25;
     : 0
  : 0.001s

[SQL]
SELECT a.id,a.empno,a.empname,a.job,a.sal,b.depno,b.depname
from emp a left join dep b on a.depno = b.depno
where a.id > 4800000
order by a.id limit 25;
     : 0
  : 0.000s
이 효율 은 가장 좋다.아무리 페이지 를 나 누 어도 시간 이 거의 일치한다.왜냐하면 그 는 조건 을 실행 한 후에 25 개의 데이터 만 스 캔 했 기 때문이다.
4.강등 전략(바 이 두 의 방법)
이 정책 은 가장 간단 하고 효과 적 입 니 다.일반적인 빅 데이터 조회 에는 검색 조건 이 있 기 때문에 100 페이지 이후 의 내용 에 관심 을 가 지 는 사람 이 없습니다.사용자 가 페이지 수 를 너무 많 을 때 오 류 를 되 돌려 주면 됩 니 다.예 를 들 어 바 이 두 는 76 페이지 만 검색 할 수 있 습 니 다.
이상 은 MySQL 백만 급 데이터 의 4 가지 조회 최적화 방식 의 상세 한 내용 입 니 다.MySQL 백만 급 데이터 조회 최적화 에 관 한 자 료 는 우리 의 다른 관련 글 을 주목 하 세 요!

좋은 웹페이지 즐겨찾기