[MySQL] MySQL 수백만 데이터 깊이 페이징 최적화 아이디어 분석

1. 사업 배경

일반적으로 프로젝트 개발에는 보고 및 분석해야 할 많은 통계 데이터가 있습니다.일반적으로 분석 후 작업 및 제품을 페이지에서 볼 수 있도록 배경에 표시됩니다.가장 일반적인 것은 다음과 같습니다. 날짜별로 필터링합니다. 이러한 종류의 통계 데이터는 시간이 지남에 따라 점차 크기가 증가할 것이며 수백만 또는 수천만 개의 데이터에 도달하는 것은 시간 문제일 뿐입니다.

2. 병목현상 재현

사용자 테이블을 생성하고 create_time 필드에 인덱스를 추가했습니다. 그리고 100w의 데이터를 테이블에 추가했습니다.
여기에 이미지 설명 삽입

여기에서는 limit paging 방법을 사용하여 처음 5개의 데이터와 마지막 5개의 데이터 간의 쿼리 시간 차이를 쿼리합니다.

처음 10개 항목을 쿼리하는 것은 기본적으로 많은 시간을 소비하지 않습니다.
여기에 이미지 설명 삽입

50w+에서 데이터를 가져올 때 쿼리는 1초가 걸립니다.
여기에 이미지 설명 삽입

SQL_NO_CACHE 키워드는 SQL 쿼리가 캐시되는 것을 방지합니다.

동일한 SQL 문, 다른 페이징 조건 및 둘 사이의 성능 차이가 너무 커서 데이터 양이 증가하면 후속 페이지를 쿼리하는 데 소요되는 시간이 논리적으로 증가합니다.

3. 문제 분석

반품 양식

일반적으로 쿼리 빈도가 높은 필드에 대한 인덱스를 생성합니다. 인덱스는 쿼리 효율성을 향상시킵니다. 위의 설명은 SELECT * FROM user를 사용하지만 모든 필드가 인덱싱되지는 않습니다. 정규화된 데이터가 인덱스 파일에서 쿼리된 후 데이터 파일에서 인덱스되지 않은 필드도 쿼리해야 합니다. 그런 다음 이 프로세스가 테이블로 다시 호출됩니다.

취재 지수

쿼리된 필드에 SELECT create_time FROM user와 같이 생성된 인덱스가 있는 경우 쿼리한 필드는 생성한 인덱스이므로 이때 데이터 파일에서 쿼리할 필요가 없으며 반환할 필요가 없습니다. 테이블에. 이 경우 커버링 인덱스라고 합니다.

이오

테이블 반환 작업은 인덱스에 따라 데이터 행을 찾은 다음 데이터 행의 기본 키 또는 고유 인덱스에 따라 특정 데이터 행을 찾기 위해 클러스터형 인덱스로 이동해야 하기 때문에 일반적으로 IO 작업입니다. 클러스터형 인덱스는 일반적으로 디스크에 저장되는 데이터 파일이므로 테이블 반환 작업을 수행할 때 디스크에서 데이터를 읽어야 하며 디스크 IO는 상대적으로 느린 작업입니다.

림티 2000,10 ?

LIMIT 2000, 10이 1~2000개의 행을 스캔할지 생각해 본 적 있나요 저처럼 2000개의 행에서 직접 데이터를 가져오고 이전 데이터는 전혀 스캔하지 않거나 테이블. 사실, 이 작성 방식에서 전체 프로세스는 데이터를 쿼리하는 것입니다.인덱스를 커버할 수 없으면 테이블로 돌아가서 데이터를 쿼리해야 합니다.

이제 뒤로 갈수록 쿼리가 느려지는 이유를 알 수 있습니다!

4. 문제 요약

우리는 이제 LIMIT의 성능이 후속 쿼리를 만났을 때 더 나쁘다는 것을 알고 있습니다. 성능이 좋지 않은 이유는 테이블로 돌아가야 하기 때문입니다. 쿼리 성능을 향상시키기 위해 테이블로 돌아갑니다.

5. 솔루션

커버링 인덱스는 데이터가 테이블로 돌아가는 것을 막을 수 있기 때문에 먼저 기본 키 id(primary key index)를 알아낸 다음 찾은 데이터를 임시 테이블로 사용하고 원본 테이블에 JOIN을 하면 된다. 5개의 쿼리 결과만 처리하면 됩니다. 데이터가 테이블로 반환되므로 IO 작업이 크게 줄어듭니다.

최적화 전후의 성능 비교

실행 효과를 살펴보겠습니다.

최적화 전: 1.4초

여기에 이미지 설명 삽입

최적화 후: 0.2초
여기에 이미지 설명 삽입

쿼리 시간이 많이 걸리는 성능이 크게 향상되었습니다. 이런 식으로 페이징된 데이터가 크면 일반 제한 쿼리만큼 느리지 않습니다.

Supongo que te gusta

Origin blog.csdn.net/u011397981/article/details/130719558
Recomendado
Clasificación