인터뷰 8부작 에세이 Mysql: (2) 데이터베이스 튜닝

1. SQL 최적화가 필요하다

데이터베이스 최적화는 MySQL, MongoDB 또는 기타 데이터베이스 등 시스템 성능을 향상시키는 데 매우 중요한 측면입니다.
SQL 최적화는 시스템 성능을 향상시키는 가장 저렴하고 가장 확실한 방법으로, 더 많은 처리량과 더 빠른 응답을 달성할 수 있습니다 . 귀하의 팀이 SQL 최적화에 탁월하다면 의심할 여지 없이 전체 대규모 시스템의 가용성이 질적으로 향상될 것이며 실제로 상사의 비용을 몇 파운드 이상 절약할 수 있습니다.
제가 겪은 프로젝트에서 이런 문제가 발생했습니다. 데이터베이스의 데이터 양이 너무 많아 쿼리 데이터의 타임아웃이 발생하고, 여러 모듈이 정상적으로 서비스를 제공할 수 없습니다. 임시 해결 방법은 오래된 데이터를 삭제하는 것이지만, 결국 증상만 치료할 뿐 근본 원인은 치료하지 못합니다.

2. SQL 최적화 방향

여기에 이미지 설명을 삽입하세요.
비용 최적화: 하드웨어>시스템 구성>데이터베이스 테이블 구조>SQL 및 인덱스.
최적화 효과: 하드웨어 < 시스템 구성 < 데이터베이스 테이블 구조 < SQL 및 인덱스.

따라서 데이터베이스 최적화는 다음 측면에서 최적화됩니다.

  • SQL 튜닝
  • 데이터베이스 인덱스
  • 불필요한 데이터를 정기적으로 삭제하고 정기적으로 조각 모음을 수행하십시오.
  • 데이터베이스 설계 - 세 가지 주요 패러다임, 필드 및 테이블 구조
  • 테이블 및 데이터베이스 세분화(수평 분할, 수직 분할)
  • MySQL 구성 최적화(my.ini 최대 동시성 수 구성, 캐시 크기 조정)
  • 저장 프로시저(속도를 높일 수 있는 모듈식 프로그래밍)
  • 마스터-슬레이브 복제, 읽기-쓰기 분리
  • 기다리다

2.1 SQL문 튜닝

SQL 성능저하의 원인 :
1. 쿼리문의 잘못된 작성
2. 인덱스 실패(데이터 변경)
3. 관련 쿼리의 조인이 너무 많음(설계 결함 또는 불가피한 요구 사항)
4. 서버 튜닝 및 다양한 매개변수 설정(버퍼링, 스레드 수, 등))

일반적인 SQL 튜닝 프로세스:

  • 프로덕션에서 느린 SQL을 확인하려면 최소 1일 동안 관찰하고 실행하세요.
  • 느린 쿼리 로그를 활성화하고 임계값을 설정합니다. 예를 들어 5초를 초과하면 느린 SQL이므로 이를 잡아 로그에 저장합니다(my.ini에서 느린 쿼리 로그 디렉터리를 지정할 수 있습니다).
  • 설명 + 느린 SQL 분석.
  • show profile은 MySQL 서버에서 SQL의 실행 세부 정보와 수명 주기를 쿼리합니다.
  • 운영 및 유지 관리 관리자 또는 DBA는 SQL 데이터베이스 서버의 매개변수 튜닝을 수행합니다.
  • 최적화된 실행 시간과 실행 계획을 확인하고, 최적화 효과가 확실하지 않으면 반복합니다.

2.2 SQL 인덱스

인덱스도 데이터베이스 설계의 일부입니다.

1. 일반적으로 다음 열에 인덱스를 생성해야 합니다.

자주 검색해야 하는 컬럼에 대해서는 검색 속도를 높이고,
기본키로 사용되는 컬럼에 대해서는 컬럼의 고유성을 강화하고 테이블 내 데이터의 배열 구조를 정리하며,
자주 사용되는 컬럼에 대해서는 검색 속도를 높일 수 있다. 연결에서 이러한 열은 주로 일부 외래 키로 연결 속도를 높일 수 있습니다;
인덱스가 정렬되어 있고 지정된 범위가 연속적이기 때문에 범위를 기준으로 자주 검색해야 하는 열에 인덱스를 생성합니다
. sorted (group by 또는 order by) 인덱스가 정렬되었으므로 **에 인덱스를 생성하여 쿼리에서 인덱스 정렬을 사용하여 정렬 쿼리 시간을 단축할 수 있으며, 자주 사용되는 열에 인덱스를 생성합니다
. 조건 판단 속도를 높이기 위해 WHERE 절에
요약은 다음과 같습니다: 고유하고 비어 있지 않으며 자주 쿼리되는 필드

2. 일부 열에 대해서는 인덱스를 생성하면 안 됩니다.

쿼리에서 거의 사용되지 않거나 참조되지 않는 열에는 인덱스를 생성하면 안 됩니다.
데이터 값이 거의 없는 열에는 인덱스를 추가하면 안 됩니다.
데이터 양이 많은 텍스트, 이미지, 비트 데이터 형식으로 정의된 열에는 인덱스를 추가하면 안 됩니다.
수정 성능이 검색 성능보다 훨씬 높으면 인덱스를 생성하면 안 됩니다. 수정 성능과 검색 성능이 모순됩니다. 인덱스를 추가하면 검색 성능은 향상되지만 수정 성능은 저하됩니다. 인덱스를 줄이면 수정 성능이 향상되고 검색 성능이 저하됩니다. 따라서 수정 성능이 검색 성능보다 훨씬 높을 경우 인덱스를 생성해서는 안 됩니다.
3. 인덱스 실패

다음과 같은 상황에서는 실행 엔진이 인덱스 사용을 포기하고 전체 테이블 스캔을 수행합니다.

where 절에 **를 사용하세요! = 또는 <> 연산자**

조건을 연결하려면 where 절에 또는 를 사용하십시오. 연결된 필드에 필드가 있지만 인덱스가 없으면 모든 필드의 인덱스가 유효하지 않습니다.

where 절 필드에서 null 값 판단을 수행하고,

where 절이 %로 시작하는 것과 같은 퍼지 일치

where 절의 인덱스에 대해 표현식 연산 또는 함수 연산을 수행합니다.

실행 엔진이 전체 테이블 스캔을 사용하는 것이 인덱스를 사용하는 것보다 빠르다고 판단하면 해당 인덱스는 사용되지 않습니다.

2.3 SQL 설계의 세 가지 주요 패러다임

(1) 데이터베이스 설계 - 세 가지 주요 패러다임, 필드 및 테이블 구조

1. 데이터베이스의 세 가지 패러다임에 따라 테이블 구조를 설계합니다. 테이블 구조를 디자인할 때 보다 효율적인 쿼리를 디자인하는 방법을 고려해야 합니다.

첫 번째 정규형: 데이터 테이블의 각 필드는 분할할 수 없는 최소 단위여야 합니다. 즉, 각 열의 원자성을 보장해야 합니다. 두 번째 정규형: 첫 번째 정규형을 만족한 후
테이블의 각 열은 고유해야 합니다. 기본 키에 의존해야 함;
세 번째 정규형: 두 번째 정규형을 만족한 후 테이블의 각 열은 간접적으로 관련되지 않고 기본 키와만 직접적으로 관련됩니다(외부 키도 직접 관련됨). 분야의 중복.
2. 기타:

정수형으로 INT 대신 TINYINT, SMALLINT, MEDIUM_INT 를 사용해 보세요. 음수가 아닌 경우
UNSIGNED VARCHAR 의 길이를 추가하여 정말 필요한 공간만 할당해 보세요.
문자열형 대신 정수형을 사용해 보세요. 단일 테이블에 필드가 너무 많습니다.
20개 이내로
피하는 것이 좋습니다. NULL 필드를 사용하면 쿼리 최적화가 어려우며 추가 인덱스 공간을 차지합니다.
select * from t를 사용하는 것은 권장되지 않습니다. 대신 특정 필드 목록을 사용하십시오. " ", 사용되지 않은 필드는 반환하지 않습니다. 클라이언트에 많은 양의 데이터를 반환하는 것을 피하십시오.데이터의 양이 너무 많으면 해당 요구 사항이 합리적인지 고려해야합니다. 테이블은 중복 필드를 통해 연결되므로 직접 JOIN을 사용하는 것보다 성능
좋습니다.
(
) 테이블에서; 조건 없이 이러한 개수를 계산하면 전체 테이블 스캔이 발생합니다.

2.4 마스터-슬레이브 복제 및 읽기-쓰기 분리

실제 프로덕션 환경에서는 데이터베이스 읽기 및 쓰기가 동일한 데이터베이스 서버에서 수행되므로 실제 요구 사항을 충족할 수 없습니다. 보안, 고가용성, 높은 동시성 측면에서 실제 요구 사항을 전혀 충족할 수 없습니다. 따라서 마스터-슬레이브 복제를 통해 데이터를 동기화하고, 읽기-쓰기 분리를 통해 데이터베이스의 동시 로드 용량을 향상시킨다.

기능: 데이터베이스 백업, 읽기-쓰기 분리, 고가용성, 클러스터링.

2. 프로세스:

각 트랜잭션이 데이터 업데이트를 완료하기 전에 마스터는 이러한 변경 사항을 바이너리 로그에 기록합니다. 바이너리 로그 쓰기가 완료된 후 마스터는 스토리지 엔진에 트랜잭션을 커밋하도록 알립니다.

슬레이브는 마스터의 바이너리 로그를 릴레이 로그에 복사합니다. 먼저 슬레이브는 작업 스레드(I/O)를 시작하고, I/O 스레드는 마스터에서 일반 연결을 연 다음 binlog 덤프 프로세스를 시작합니다. binlog 덤프 프로세스는 마스터의 바이너리 로그에서 이벤트를 읽습니다. 마스터를 따라잡으면 대기 상태에서 마스터가 새 이벤트를 생성할 때까지 기다립니다. I/O 스레드는 이러한 이벤트를 릴레이 로그에 기록합니다.

SQL 슬레이브 스레드(sql 슬레이브 스레드)는 프로세스의 마지막 단계를 처리하며, sql 스레드는 릴레이 로그에서 이벤트를 읽고 이벤트를 재생하여 슬레이브 데이터를 마스터의 데이터와 일치하도록 업데이트합니다. I/O 스레드에 연결되어 일관성을 유지하며 릴레이 로그는 일반적으로 OS 캐시에 있으므로 릴레이 로그의 오버헤드는 매우 작습니다.

여기에 이미지 설명을 삽입하세요.

2.5 하위 데이터베이스 및 하위 테이블

하위 데이터베이스 및 하위 테이블

마스터-슬레이브 복제에서는 슬레이브 데이터베이스는 계속 늘려서 확장할 수 있지만, 마스터 데이터베이스는 쉽게 늘릴 수 없으므로, 이때 테이블과 데이터베이스를 분할하는 것을 고려할 수 있습니다.

1. 분할 테이블 방법

가로 분할(행 기준), 세로 분할(열 기준)

수직 분할: 수직 분할은 테이블을 모듈에 따라 서로 다른 데이터베이스로 나누는 것으로, 데이터베이스는 모듈 및 기능에 따라 테이블을 나누는 서비스 지향적인 경향이 있습니다.

수평 샤딩은 주로 "대량 데이터베이스 데이터 볼륨 문제"를 해결하는 데 사용됩니다.

수평 분할: 수평 분할은 특정 규칙에 따라 테이블의 데이터를 다른 테이블이나 데이터베이스로 나누는 것입니다. 예를 들어 시간, 계정 규칙, 연도, 모듈로 알고리즘 등
2. 테이블 분할 시나리오

경험에 따르면 mysql 테이블 데이터는 일반적으로 수백만 수준에 도달하며 쿼리 효율성은 매우 낮습니다.
테이블의 일부 필드는 큰 값을 가지며 거의 사용되지 않습니다. 이러한 필드는 별도의 테이블로 분리될 수 있으며 테스트 점수와 같은 외래 키를 통해 관련될 수 있습니다. 우리는 일반적으로 테스트 세부 사항이 아닌 점수에 중점을 둡니다.
3. 수평 테이블 분할 전략

시간별 테이블 분할: 웨이보 데이터 등 데이터의 유효성이 강한 경우 월별로 분할할 수 있습니다.
테이블을 간격별로 나누기: 예를 들어 100만~100만 개의 사용자 테이블에는 하나의 테이블을 사용하고, 100만~200만 개의 사용자 테이블에는 하나의 테이블을 사용합니다.
해시 테이블 세분화: 특정 해시 알고리즘에 따라 원본 대상 ID 또는 이름을 통해 데이터 저장소의 테이블 이름을 계산합니다.
4. 테이블 분할의 단점:
페이징 쿼리가 어렵고
쿼리가 매우 제한적

2.6 아키텍처 최적화

애플리케이션과 데이터베이스 사이에 Redis 또는 Memcache와 같은 캐싱 서비스를 추가합니다.

여기에 이미지 설명을 삽입하세요.

쿼리 요청을 받은 후 먼저 캐시에 쿼리하여 캐시에 데이터가 있는지 확인하고, 데이터가 있으면 바로 애플리케이션으로 반환하고, 데이터가 없으면 데이터베이스를 다시 쿼리하여 로드합니다. 캐시에 저장하면 데이터베이스에 대한 액세스 횟수가 크게 줄어들고 당연히 데이터베이스 성능도 향상됩니다. 그러나 분산 캐시를 도입한 후에는 시스템에서 캐시 침투, 캐시 고장 및 캐시 사태를 처리하는 방법을 고려해야 합니다.

추천

출처blog.csdn.net/weixin_42774617/article/details/132245346