6.1 소개

이제 이론에서 실습으로 넘어 갑시다.

“이론적으로는 이론과 실제 사이에 차이가 없습니다. 실제로는 그렇습니다."

우리는 현실 세계에 살고 있으며 모든 소프트웨어 제품은 궁극적으로 살아있는 사람을 위해 만들어집니다. 그리고이 살아있는 사람들은 느리게로드되는 사이트와 느려지는 프로그램에 매우 짜증이납니다.

그리고 데이터베이스 쿼리가 1초 이상 걸리는 경우 이는 허용되지 않습니다 . 사용자는 너무 느린 페이지/기능이 있는 제품을 사용하지 않을 것입니다.

그러나 종종 한 페이지를 표시하기 위해 데이터베이스에 대해 수십 개의 쿼리를 수행해야 합니다. 그리고 순차적으로 실행되면 더 이상 두 번째 제한이 없지만 요청당 100ms라고 가정해 보겠습니다.

다음은 프로그래머가 데이터베이스 쿼리 속도를 높이는 5가지 방법입니다.

  1. 데이터베이스의 테이블에 인덱스를 추가합니다.
  2. 쿼리 재작성 및 최적화.
  3. 데이터베이스 측에서 캐싱을 활성화(및 구성)합니다.
  4. 클라이언트 측에서 캐싱을 활성화합니다.
  5. 데이터베이스 비정규화를 수행합니다.

대부분의 경우 이러한 모든 사항에 이미 익숙하므로 다음은 실용적인 조언일 뿐입니다.

6.2 지수

데이터베이스 작업이 거의 모든 사이트 작업의 대부분을 차지한다는 것은 비밀이 아닙니다. 그리고 웹 애플리케이션의 병목 현상이 가장 자주 발생하는 데이터베이스와 함께 작동합니다.

이 기사에서는 MySQL 사용에 대한 실용적인 조언을 제공하고자 합니다.

나는 즉시 말할 것입니다 :

  • 이 기사는 MySQL에 대해 작성되었지만 일반적인 사항은 모든 DBMS에 해당될 수 있습니다.
  • 기사에 쓰인 모든 내용은 제 개인적인 관점이며 궁극적인 진실은 아닙니다.
  • 조언은 새로운 척하지 않으며 읽은 문헌과 개인적인 경험을 일반화한 결과입니다.
  • 이 기사의 틀 내에서 MySQL 구성 문제는 다루지 않겠습니다.

MySQL을 사용할 때 발생하는 문제는 중요도에 따라 다음 세 그룹으로 나눌 수 있습니다.

  1. 인덱스의 미사용 또는 오용.
  2. 잘못된 데이터베이스 구조.
  3. 잘못된 \ 최적이 아닌 SQL 쿼리.

각 그룹에 대해 자세히 살펴보겠습니다.

인덱스 사용

인덱스를 사용하지 않거나 오용하면 쿼리 속도가 느려지는 경우가 가장 많습니다. 인덱스가 작동하는 메커니즘에 익숙하지 않거나 아직 매뉴얼에서 이에 대해 읽지 않은 사람들에게 꼭 읽어 보라고 강력히 권합니다.

색인 사용 팁:

  • 모든 것을 인덱싱할 필요는 없습니다 . 종종 사람들은 의미를 이해하지 못한 채 테이블의 모든 필드를 인덱싱합니다. 색인은 가져오기 속도를 높이지만 행 삽입 및 업데이트 속도를 늦추므로 각 색인의 선택은 의미가 있어야 합니다.
  • 인덱스를 특징짓는 주요 매개변수 중 하나는 인덱스에 있는 서로 다른 요소의 수인 선택성입니다. 2개 또는 3개의 가능한 값이 있는 필드를 인덱싱하는 것은 의미가 없습니다. 이러한 인덱스의 이점은 거의 없습니다.
  • 인덱스 선택은 주어진 테이블에 대한 모든 쿼리 분석으로 시작해야 합니다. 매우 자주 이러한 분석 후에 3개 또는 4개의 인덱스 대신 하나의 복합 인덱스를 만들 수 있습니다.
  • 복합 인덱스를 사용할 때 인덱스의 필드 순서가 중요합니다.
  • 커버링 인덱스를 잊지 마세요. 쿼리의 모든 데이터를 인덱스에서 검색할 수 있는 경우 MySQL은 테이블에 직접 액세스하지 않습니다. 이러한 요청은 매우 빠르게 실행됩니다. SELECT name FROM user WHERE login='test'예를 들어 인덱스(로그인, 이름)가 있는 쿼리의 경우 테이블에 대한 액세스가 필요하지 않습니다. 경우에 따라 복합 인덱스에 추가 필드를 추가하는 것이 좋습니다. 이렇게 하면 인덱스가 커버되고 쿼리 속도가 빨라집니다.
  • 행 인덱스의 경우 행의 일부만 인덱싱하는 것으로 충분한 경우가 많습니다. 이렇게 하면 인덱스 크기를 크게 줄일 수 있습니다.
  • %시작 부분에 있으면 인덱스 LIKE(SELECT * FROM table WHERE field LIKE '%test')가 사용되지 않습니다.
  • FULLTEXT 인덱스는 MATCH ... AGAINST 구문 에만 사용됩니다 .

6.3 데이터베이스 구조

잘 설계된 데이터베이스는 빠르고 효율적인 데이터베이스 작업의 핵심입니다. 반면에 잘못 설계된 데이터베이스는 개발자에게 항상 골칫거리입니다.

데이터베이스 디자인 팁:

  1. 가능한 가장 작은 데이터 유형을 사용하십시오. 데이터 유형이 클수록 테이블이 클수록 데이터를 가져오는 데 더 많은 디스크 액세스가 필요합니다. 매우 편리한 절차를 사용하여 SELECT * FROM table_name PROCEDURE ANALYSE();가능한 최소 데이터 유형을 결정합니다.
  2. 디자인 단계에서 정상적인 형태를 관찰하십시오. 종종 프로그래머는 이 단계에서 이미 비정규화에 의존합니다. 그러나 대부분의 경우 프로젝트 초기에는 이것이 어떻게 발생할 수 있는지 명확하지 않습니다. 테이블을 비정규화하는 것이 최적이 아닌 비정규화로 인해 어려움을 겪는 것보다 훨씬 쉽습니다. 때로는 JOIN잘못 비정규화된 테이블보다 빠르게 작동합니다.
  3. NULL의식적으로 필요한 경우가 아니면 열을 사용하지 마십시오 .

6.4 SQL 쿼리.

쿼리가 가능한 한 빠르도록 모든 쿼리를 네이티브 SQL로 다시 작성하려는 경우가 많습니다. 이 작업을 수행하기로 결정한 경우 다음과 같은 몇 가지 팁이 있습니다.

  1. 루프에서 요청을 피하십시오. SQL은 집합의 언어이고 쿼리 작성은 함수의 언어가 아닌 집합의 언어로 접근해야 합니다.
  2. *쿼리에서 (별표)를 사용하지 마십시오 . 선택한 필드를 자유롭게 나열하십시오. 이렇게 하면 가져오고 보내는 데이터의 양이 줄어듭니다. 또한 색인을 포함하는 것을 잊지 마십시오. 테이블의 모든 필드를 선택하더라도 나열하는 것이 좋습니다. 첫째 , 코드의 가독성을 향상시킵니다. 별표를 사용하면 테이블을 살펴보지 않고는 테이블에 어떤 필드가 있는지 알 수 없습니다. 둘째 , 오늘 테이블에는 5개의 INT 열이 있고 한 달 후 TEXTBLOB가 하나 더 추가되었으며 별표는 그대로 유지되었습니다.
  3. 페이지를 매길 때 총 레코드 수를 가져오려면 SQL_CALC_FOUND_ROWSSELECT FOUND_ROWS();사용 시 SQL_CALC_FOUND_ROWS MySQL선택한 행 수를 캐시하고(LIMIT 적용 전) 사용 시 SELECT FOUND_ROWS()쿼리를 다시 실행할 필요 없이 이 캐시된 값만 반환합니다.
  4. INSERT다중 삽입에 대한 구문이 있다는 것을 잊지 마십시오 . 하나의 쿼리는 루프의 여러 쿼리보다 훨씬 빠르게 실행됩니다.
  5. LIMIT모든 데이터가 필요하지 않은 곳에서 사용하십시오 .
  6. 및 또는 선택 후, 종종 대신 INSERT… ON DUPLICATE KEY UPDATE…에 사용합니다 .INSERTUPDATEREPLACE
  7. 이 놀라운 기능을 잊지 마세요 GROUP_CONCAT. 복잡한 쿼리에 도움이 될 수 있습니다.