MySQL 천만 급 데 이 터 는 어떻게 페이지 를 빠르게 나 눌 수 있 습 니까?
백 엔 드 개발 에 서 는 한 번 에 너무 많은 데 이 터 를 불 러 와 메모리,디스크 IO 가 너무 많이 들 어 가 는 것 을 방지 하기 위해 페이지 별로 보 여 줘 야 하 는데 이 럴 때 는 MySQL 의 LIMIT 키 워드 를 사용 해 야 합 니 다.그런데 LIMIT 가 페이지 를 나 누 면 만사 가 다 잘 될 것 같 아 요?Too young,too simple 아,LIMIT 가 데이터 양 이 많 을 때 발생 할 수 있 는 문 제 는 깊이 페이지 입 니 다.
케이스
여기 서 나 는 전자상거래 주문 의 상세 한 상황 을 표시 하 는 것 을 배경 으로 예 를 들 어 새 표 는 다음 과 같다.
CREATE TABLE `cps_user_order_detail` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT ' ',
`user_id` varchar(32) NOT NULL DEFAULT '' COMMENT ' ID',
`order_id` bigint(20) DEFAULT NULL COMMENT ' id',
`sku_id` bigint(20) unsigned NOT NULL COMMENT ' ID',
`order_time` datetime DEFAULT NULL COMMENT ' , yyyy-MM-dd HH:mm:ss',
PRIMARY KEY (`id`),
KEY `idx_time_user` (`order_time`,`user_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT=' ';
그리고 표 에 120 W 개의 데 이 터 를 수 동 으로 삽입 합 니 다.현재 필요 한 것 이 있 습 니 다.페이지 별로 사용자 의 주문 상세 정 보 를 보 여 주 고 다음 시간 에 따라 순 서 를 바 꿉 니 다.
표 구조 가 간소화 되 고 수요 도 간단 하 다.그래서 코드 를 주룩주룩 쓰 고 테스트 가 시작 되 었 습 니 다.초기 에 모든 것 이 정상 적 으로 운행 되 었 으 나 주문량 이 계속 증가 함 에 따라 시스템 이 점점 느 려 지고 가끔 느 린 조 회 를 보고 하 는 것 을 발견 했다.
이 럴 때 LIMIT 의 오프셋 문제 라 고 생각해 야 합 니 다.맞습니다.SQL 이 아름 답지 않 은 것 이 아니 라 MySQL 자체 의 메커니즘 입 니 다.
여기 서 저 는 간단하게 두 개의 SQL 을 예 로 들 면 다음 과 같은 그림 입 니 다.각각 100 W 와 100 W 의 위치 에서 페이지 를 옮 기 면 시간의 차이 가 매우 크다 는 것 을 알 수 있 습 니 다.이것 은 다른 데이터 연산 과 처리 시간 이 아니 라 단일 SQL 의 조회 에 1 초 이상 걸 립 니 다.사용자 에 게 제공 하 는 기능 에 서 는 용납 할 수 없습니다(전자상거래 에서 인 터 페 이 스 를 요구 하 는 RT 는 200 ms 를 초과 하지 않 습 니 다).
여기 서 우 리 는 다음 그림 과 같이 집행 계획 을 다시 한번 봅 시다.
실행 계획 Extra 열 에 나타 날 수 있 는 값 과 의 미 를 소개 합 니 다.
그리고 두 번 째 문 구 는 LIMIT 1000000,6 은 색인 을 전혀 가지 않 았 고 type 열의 값 은 ALL 이 며 전체 표 스 캔 이 분명 합 니 다.또한 Extra 열 필드 의 Using where 는 리 턴 이 발생 했 음 을 표시 하고 Using filesort 는 ORDER BY 를 표시 할 때 파일 정렬 이 발생 했 습 니 다.그래서 여기 서 두 가지 가 느 렸 습 니 다.하 나 는 파일 정렬 에 시간 이 너무 많이 걸 리 는 것 입 니 다.다른 하 나 는 조건 에 따라 관련 데 이 터 를 선별 한 후에 오프셋 표 에 따라 모든 값 을 가 져 와 야 합 니 다.위의 어느 점 이 든 LIMIT 편 이 량 이 너무 많아 서 생 긴 것 이기 때문에 실제 개발 환경 에 서 는 비 통계표 급 이 백만 원 을 초과 해 서 는 안 된다 는 요구 가 자주 발생 한다.
최적화 하 다.
원인 분석 이 끝나 면 LIMIT 깊이 페이지 는 실제 개발 에서 어떻게 최적화 할 것 인가?여기 소 협 은 두 가지 방안 을 주 었 다.
하 나 는 메 인 키 색인 을 통 해 최적화 하 는 것 이다.무슨 뜻 이 죠?바로 위의 문 구 를 다음 과 같이 수정 하 는 것 이다.
SELECT * FROM cps_user_order_detail d WHERE d.id > #{maxId} AND d.order_time>'2020-8-5 00:00:00' ORDER BY d.order_time LIMIT 6;
위의 코드 와 같이 페이지 도 나 뉘 지만 maxId 의 제한 조건 이 있 습 니 다.이것 은 무슨 뜻 입 니까?maxId 는 바로 이전 페이지 의 최대 메 인 키 Id 입 니 다.따라서 이 방식 을 사용 하 는 전제 조건:1)메 인 키 는 UUID 가 아 닌 자체 증가 해 야 하 며 전단 은 기본 페이지 매개 변수 인 pageno,pageSize 를 전달 하 는 것 외 에 매번 이전 페이지 의 최대 Id 를 가 져 와 야 한다.2)이 방식 은 무 작위 로 페이지 를 넘 기 는 것 을 지원 하지 않 는 다.즉,상하 로 페이지 를 넘 길 수 밖 에 없다 는 것 이다.아래 그림 에서 보 듯 이 어떤 유명 전자상거래 의 실제 페이지 이다.둘째,Elastic Search 검색엔진(후진 색인 기반)을 통 해 실제 타 오 바 오 와 같은 전자상거래 들 은 기본적으로 모든 상품 을 ES 검색엔진 에 넣 는 것 이다(그러면 대량의 데 이 터 를 MySQL 에 넣 는 것 은 불가능 하고 Redis 에 넣 는 것 도 현실 적 이지 않다).그러나 ES 검색엔진 을 사용 하 더 라 도 깊이 있 는 페이지 나 누 기 문제 가 발생 할 수 있 습 니 다.이 럴 때 는 어떻게 해 야 합 니까?정 답 은 커서 스크롤 을 통 해이 점 에 대해 서 는 깊이 파고 들 지 않 고 관심 있 는 것 은 연 구 를 할 수 있다.
작은 매듭
이 블 로 그 를 쓴 것 은 얼마 전 개발 과정 에서 실제로 겪 었 고 바이트 면접 에서 도 면접 관 과 토론 을 했 기 때문이다.LIMIT 의 제한 과 최 적 화 를 알 고 면접 에서 가산 점 항목 이 라 고 할 수 있 습 니 다.MySQL 최적화 가 바로 색인 을 만 드 는 것 이 라 고 할 수 없습니다.SQL 을 조정 하 는 것(실제 개발 에서 이 두 가지 최적화 방안 의 효 과 는 매우 적 습 니 다).MySQL 이 최적화 되면 그렇게 많은 미들웨어 가 생기 지 않 을 것 이다.
저 는 소 협 루피 입 니 다.기술 을 사랑 하고 나 누 기 를 좋아 합 니 다.
이상 은 MySQL 천만 급 데이터 양 이 어떻게 페이지 를 빨리 나 누 는 지 에 대한 상세 한 내용 입 니 다.MySQL 의 빠 른 페이지 나 누 기 에 관 한 자 료 는 저희 의 다른 관련 글 을 주목 하 세 요!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Redash를 사용할 때 몰랐던 SQL을 쓰는 법을 배웠습니다.최근 redash에서 sql을 쓸 기회가 많고, 이런 쓰는 방법이 있었는지와 sql에 대해 공부를 다시하고 있기 때문에 배운 것을 여기에 씁니다. Redash란? 월별로 데이터를 표시하고 싶습니다 주별로 데이터를 표...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.