많은 양의 데이터, 페이징 쿼리가 느린 어떻게 최적화?

수십 데이터베이스 쿼리 테이블에서 레코드의 수천의 필요성, 모두 한 번 쿼리 결과 데이터의 양이 증가 특히 분명하다 특히으로, 매우 느리게 될 것입니다 때, 당신은 페이징 쿼리를 사용해야합니다. 데이터베이스 쿼리 페이지를 들면, 많은 방법과 최적화 지점이있다.

내가 알고있는 몇 가지 방법에 대해 다음 잠시.

준비

테스트를 위해 아래의 수를 최적화하기 위해, 후술하는 테이블을 보유한다.

  • 表 名 : order_history

  • 설명 : 비즈니스의 주문 내역 표

  • 주요 분야 : 부호없는 INT 아이디, TINYINT (4) INT 타입

  • 필드 37 개 테이블 필드 및 다른 큰 텍스트 데이터의 총 VARCHAR (500)까지 ID 필드 인덱스이고, 증분은 포함되지 않는다.

  • 데이터 볼륨 : 5709294

  • MySQL 버젼 : 5.7.16 테스트 테이블의 백만 라인을보고는 자신을 테스트해야하는 경우가 삽입되는 데이터 테스트하는 쉘 스크립트를 작성할 수, 쉬운 일이 아니다. 다음의 모든 SQL 문을 실행 환경은 기본 테스트 결과는 다음, 변경하지 않은 :

     

select count(*) from orders_history;

돌아 가기 : 5,709,294를

세 개의 질의 시간이 있었다 :

  • 8903 MS

  • 8323 MS

  • 8401 MS

일반 페이징 쿼리

간단한 한계 절을 사용하여 일반 페이징 쿼리는 달성 될 수있다. 문 다음 절을 제한 :

SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset

LIMIT 절은 SELECT 문에 의해 반환 된 레코드의 수를 지정하는 데 사용할 수 있습니다. 다음 사항에 유의하십시오

  • 첫 번째 인수는에서 처음 반환에게 관심의 오프셋 행을 지정합니다  0시작

  • 두 번째 파라미터는 반환되는 행의 최대 수를 지정

  • 하나 개의 인수를 주어진 경우 그것은 반환 된 행의 최대 수를 나타냅니다

  • -1 번째 파라미터는 모든 행의 끝에 레코드들의 세트로부터 오프셋을 검색 할

  • 옵셋 0은 최초의 행 (1 대신의) 인

다음은 응용 프로그램의 예입니다 :

select * from orders_history where type=8 limit 1000,10;

이 문서는 테이블 orders_history에서 문 쿼리합니다  offset:1000제에, 즉, 데이터의 시작 후 1010 개 데이터를 제 (1001) 10 ( 1001<=id<=1010).

위의 기본에 해당하는 마스터 키 (보통 ID) 정렬 결과를 사용하여 데이터 테이블 레코드 :

select * from orders_history where type=8 order by id limit 10000,10;

세 개의 질의 시간이 있었다 :

  • 3040 MS

  • 3063 MS

  • 3018 MS

이 쿼리 시간의 다음 테스트 쿼리 충격 기록 양 님의 질문에 답변

  1.  
    * 선택 orders_history 발을 여기서 TYPE = 8 한계 10000, 1;
  2.  
    * 선택 orders_history 발을 여기서 TYPE = 8 한계 10000, 10;
  3.  
    * 선택 orders_history 발을 여기서 TYPE = 8 한계 10000 100;
  4.  
    * 선택 orders_history 발을 여기서 TYPE = 8 한계 10000, 1000;
  5.  
    * 선택 orders_history 발을 여기서 TYPE = 8 한계 10000, 10000;

다음과 같이 세 가지 질의 시간은 다음과 같습니다 :

  • 기록을 조회 : 3072ms의 3092ms의 3002ms를

  • 쿼리 10 기록 : 3081ms의 3077ms의 3032ms

  • 3118ms의 3200ms의 3128ms : (100 개) 기록을 조회합니다

  • 검색어 1000 기록 : 3412ms의 3468ms의 3394ms

  • 쿼리 만 개 기록 : 3749ms의 3802ms의 3696ms

나는 또한 점점 더, 너무 걸리는 시간 조회 기록을 금액으로 수십 번 쿼리 관점에서 질의 시간이 100 인 미만의 질의 기록 양의 시간에, 거의 확실하다, 기본적으로 차이가 없습니다 쿼리 시간을했다 점점 더 많은.

문의 테스트를 오프셋 :

  1.  
    * 선택 orders_history 발을 여기서 TYPE = 8 한도 100, 100;
  2.  
    * 선택 orders_history 발을 여기서 TYPE = 8 한도 1,000, 100;
  3.  
    * 선택 orders_history 발을 여기서 TYPE = 8 한계 10000 100;
  4.  
    * 선택 orders_history 발을 여기서 TYPE = 8 한도 100,000, 100;
  5.  
    * 선택 orders_history 발을 여기서 TYPE = 8 제한 1000000 100;

다음과 같이 세 가지 질의 시간은 다음과 같습니다 :

  • 쿼리 (100)는 오프셋 :은 25ms의 24ms의 24ms

  • 쿼리 (1000)는 오프셋 : 78ms의 76ms의 77ms

  • 쿼리 만 오프셋 : 3092ms의 3212ms의 3128ms

  • 3878ms의 3812ms의 3798ms : (100) 000 오프셋을 조회합니다

  • 쿼리 1 백만 오프셋 : 14608ms 14062ms 14700ms을

쿼리의 증가로 상쇄 한 후, 특히 쿼리는 오프셋 (offset)보다 10 만, 쿼리 시간의 급격한 증가이다.

이 페이징 쿼리는 데이터베이스에서 첫 번째 레코드 스캔을 시작, 그래서 더 뒤로, 느린 쿼리 속도,하지만 더 많은 데이터 쿼리, 쿼리는 전체 속도가 느려집니다.

서브 쿼리 최적화의 사용

제 1 위치는 위치 ID 및 나중에 문의 오프셋이 방법으로,이 방법은 ID 단위의 경우에도 적용 가능하다.

  1.  
    * 선택 orders_history 발을 여기서 TYPE = 8 제한 100000, 1;
  2.  
    선택 자료 orders_history 발을 여기서 TYPE = 8 제한 100000, 1;
  3.  
    * 선택 orders_history에서 어디 TYPE = 8
  4.  
    ID> = ( 선택 자료 orders_history에서 어디 TYPE = 8 제한 100000, 1)
  5.  
    제한 100;
  6.  
    * 선택 orders_history 발을 여기서 TYPE = 8 한도 100,000, 100;

다음과 같이 쿼리 시간은 4 문은 다음과 같습니다

  • 명령문의 제 1 조 : 3674ms

  • 제 2 문 : 1315ms

  • 명령문의 제 3 조 : 1327ms

  • 제 4 문 : 3710ms

위의 질의에 대한 것을 참고 :

  • 첫 번째 문 두 번째 문장의 비교 : 대신 선택 사용하는 ID를 선택 * 속도는 3 배 증가

  • 비교 제 2 조 및 3 문 문 : 수십 밀리 초의 속도 차이

  • 제 3 조 및 제 4 조 문장 문장의 비교 : 증가 속도에서 ID를 선택 혜택, 제 3 문 쿼리 속도가 3 배 증가

원래 일반 쿼리 방법에 비해이 방법으로 여러 번 빨라집니다. 추천 도서 : 전문 솔루션 MySQL의 쿼리 느리고 성능 저하!

이드 최적화를 사용하여 정의

이 지속적으로 증가하고 데이터 테이블의 ID가, 우리는 페이지와 쿼리 쿼리 수, 당신은 사이 ID를 사용할 수 있으며 쿼리 레코드의 수에 따라 쿼리의 범위의 ID를 계산할 수 있다고 가정합니다 :

  1.  
    * 선택 orders_history에서 TYPE = 2
  2.  
    ID 간의 1,000,000 1,000,100 한도 100;

쿼리 시간 : 15ms의의 12ms의 9ms

크게 검색 속도를 최적화 할 수 있습니다이 쿼리는 실질적으로 밀리 초 수십 내에 완료 할 수 있습니다. 만 사용 제한은 ID의 상황을 명확하게 인식하지만, 시간 테이블 작성의 대부분은 페이징 쿼리에 대한 편의를 많이 가져 기본적인 id 필드를 추가합니다.

서면 다른 종류가있을 수 있습니다 :

select * from orders_history where id >= 1000001 limit 100;

물론, 또한 관련 멀티 테이블 쿼리, 쿼리 ID 테이블 쿼리의 다른 세트를 사용하는 경우이 방법이 주로 사용되며, 조회 할 수있는 방법으로 사용할 수 있습니다 :

  1.  
    * 선택 orders_history에서 어디 ID
  2.  
    ( ORDER_ID 선택 trade_2에서 어디 제품 = '펜')
  3.  
    제한 100;

이런 식으로 쿼리가주의해야 할 : 일부 MySQL의 버전이 IN 절에서 제한의 사용을 지원하지 않습니다.

임시 테이블의 사용을 최적화

이 최적화를 조회 할 속하지 않는 이러한 방법으로, 여기에 방법을 제공됩니다.

질문 ID가 최적화 정의를 들어, 같은 때 사용 이력 테이블로, ID가 지속적으로 증가하고 있지만, 일부 시나리오에 필요, 또는 ID 페이징을 기록하는 임시 저장 테이블을 사용하는 것이 좋습니다 데이터에 문제가없는 경우 등장 ID는 쿼리에서 페이징을 사용합니다. 이것은 크게 데이터 수천만 특히 양, 기존의 페이징 쿼리 속도를 향상시킬 수 있습니다.

데이터 테이블의 ID 정보

정상적인 상황에서는 데이터베이스에서 테이블의 설립은 id 필드가 그래서 질문을 용이하게하기 위해, 각 테이블을 증가 추가하도록 강요하는 경우.

같은 주문과 다른 매우 큰 데이터베이스와 같은 데이터의 양이 일반적으로 하위 라이브러리 하위 테이블이됩니다. 이번에는 고유 식별자 ID를 데이터베이스로 사용하지 않는 것이 좋습니다,하지만 고유 ID를 생성하는 마이크로 그리드의 높은 동시성을 사용해야하고, 데이터 테이블에서 추가 필드의 사용은 고유 식별자를 저장합니다.

처음 사용 범위 질의 위치 ID (또는 인덱스)를 사용하고 쿼리 속도를 개선 할 수있는 데이터를 여러 번 찾기 위해 인덱스를 사용합니다. 즉, 제 ID를 선택하고 * 선택되고;

HTTPS : //blog.csdn.net/youanyyou/article/details/95558514에서 참조

 

추천

출처www.cnblogs.com/fengzifengfeng/p/11531969.html