>  기사  >  데이터 베이스  >  MySQL에서 SQL 문은 어떻게 실행됩니까?

MySQL에서 SQL 문은 어떻게 실행됩니까?

不言
不言앞으로
2019-04-11 11:44:512290검색

이 글의 내용은 MySQL에서 SQL 문을 실행하는 방법에 관한 것입니다. 도움이 필요한 친구들이 참고할 수 있기를 바랍니다.

이 기사에서는 MySQL 내에서 sql 쿼리가 어떻게 흐르는지, sql 문의 업데이트가 완료되는지를 포함하여 MySQL에서 다음 sql 문의 실행 프로세스를 분석합니다.

분석에 앞서 MySQL의 인프라를 살펴보도록 하겠습니다. MySQL이 어떤 구성요소로 구성되어 있는지, 이러한 구성요소의 기능이 무엇인지를 아는 것은 이러한 문제를 이해하고 해결하는 데 도움이 될 수 있습니다.

A MySQL 인프라 분석

1.1 MySQL 기본 아키텍처 개요

다음 그림은 MySQL의 간략한 아키텍처 다이어그램입니다. 아래 그림을 보면 MySQL 내에서 사용자의 SQL 문이 어떻게 실행되는지 명확하게 알 수 있습니다.

모든 사람의 이해를 돕기 위해 아래 그림에 포함된 일부 구성 요소의 기본 기능을 간략하게 소개하겠습니다. 이러한 구성 요소의 기능은 섹션 1.2에서 자세히 소개됩니다.

커넥터: 신원 인증 및 권한 관련(MySQL에 로그인할 때).

쿼리 캐시: 쿼리 문을 실행할 때 캐시가 먼저 쿼리됩니다(MySQL 8.0 버전 이후에는 이 기능이 그다지 실용적이지 않기 때문에 제거됨).

Analyzer: 캐시에 맞지 않으면 SQL 문은 분석기를 통과합니다. 직설적으로 말하면 분석기는 먼저 SQL 문이 수행하는 작업을 확인한 다음 SQL 문의 구문을 확인해야 합니다. 맞습니다.

Optimizer: MySQL이 최적의 솔루션으로 간주하는 것에 따라 실행합니다.

Executor: 명령문을 실행하고 스토리지 엔진에서 데이터를 반환합니다.

MySQL에서 SQL 문은 어떻게 실행됩니까?

간단히 말하면 MySQL은 주로 서버 계층과 스토리지 엔진 계층으로 나뉩니다.

서버 계층: 주로 커넥터, 쿼리 캐시, 분석기, 최적화 프로그램, 실행기 등이 포함되며 모든 크로스 스토리지 엔진 함수 저장 프로시저, 트리거, 뷰, 함수 등과 같은 모든 기능이 이 계층에서 구현되며 일반 로그 모듈인 binglog 로그 모듈도 있습니다.

스토리지 엔진: 주로 데이터 저장 및 읽기를 담당하며, 교체 가능한 플러그인 아키텍처를 사용하고 InnoDB, MyISAM 및 Memory와 같은 여러 스토리지 엔진을 지원합니다. InnoDB 엔진에는 자체 로그 모듈 리두로그 모듈이 있습니다. 현재 가장 일반적으로 사용되는 스토리지 엔진은 MySQL 버전 5.5.5부터 기본 스토리지 엔진으로 사용되어 온 InnoDB입니다.

1.2 서버 계층의 기본 구성 요소 소개

1) 커넥터

커넥터는 상위 게이트키퍼와 마찬가지로 주로 신원 인증 및 권한과 관련된 기능과 관련됩니다.

주로 사용자 로그인 데이터베이스, 계정 비밀번호 확인, 권한 및 기타 작업을 포함한 사용자 신원 인증을 담당합니다. 사용자 계정 비밀번호가 통과된 경우 커넥터는 권한 테이블에서 사용자의 모든 권한을 쿼리한 다음 이 연결 권한 논리 판단은 이때 읽은 권한 데이터에 따라 달라집니다. 즉, 연결이 끊어지지 않는 한 관리자가 사용자 권한을 수정하더라도 사용자는 영향을 받지 않습니다.

2) 쿼리 캐시(MySQL 8.0 버전 이후 제거됨)

쿼리 캐시는 주로 우리가 실행하는 SELECT 문과 해당 문의 결과 집합을 캐시하는 데 사용됩니다.

연결이 설정된 후 쿼리 문을 실행하면 캐시가 먼저 쿼리됩니다. MySQL은 먼저 SQL이 실행되었는지 확인하고 이를 Key-Value 형식으로 메모리에 캐시합니다. Value는 결과 집합입니다. 캐시 키가 적중되면 클라이언트에 직접 반환됩니다. 적중이 없으면 후속 작업이 완료되면 다음 호출을 용이하게 하기 위해 결과가 캐시됩니다. 물론 실제로 캐시 질의가 실행될 때 해당 테이블에 대한 질의 조건이 있는지 확인하기 위해 사용자의 권한을 검증하게 됩니다.

실제 비즈니스 시나리오에서는 쿼리 캐시 오류가 매우 자주 발생할 수 있으므로 MySQL 쿼리에는 캐시를 사용하지 않는 것이 좋습니다. 자주 업데이트되지 않는 데이터의 경우에도 캐싱을 사용할 수 있습니다.

따라서 일반적으로 대부분의 경우 쿼리 캐시를 사용하지 않는 것이 좋습니다.

MySQL 버전 8.0 이후 캐시 기능이 삭제되었습니다. 관계자들도 이 기능이 실제 적용 시나리오가 거의 없다고 판단하여 간단히 삭제했습니다.

3) 분석기

MySQL이 캐시에 도달하지 않으면 분석기로 들어갑니다. 분석기는 주로 SQL 문의 용도를 분석하는 데 사용됩니다.

첫 번째 step , 어휘 분석 , SQL 문은 여러 문자열로 구성되어 있으므로 먼저 select, 쿼리할 테이블, 필드 이름, 쿼리 조건 등 키워드를 추출해야 합니다. 이러한 작업을 완료하면 두 번째 단계로 들어갑니다.

두 번째 단계인 구문 분석은 주로 입력한 SQL이 정확하고 MySQL의 구문과 일치하는지 확인하는 것입니다.

이 2단계를 완료하면 MySQL 실행을 시작할 준비가 되었습니다. 실행 방법과 최상의 결과를 얻으려면 어떻게 해야 할까요? 이때 옵티마이저가 작동해야 합니다.

4) Optimizer

Optimizer의 역할은 여러 인덱스를 사용하는 경우와 같이 최적의 실행 계획으로 간주되는 것을 실행하는 것입니다(때로는 최적이 아닐 수도 있습니다. 이 기사에서는 이 지식에 대한 심층적인 설명을 다룹니다). . 인덱스를 선택하는 방법, 여러 테이블을 쿼리할 때 연결 순서를 선택하는 방법 등.

옵티마이저를 거쳐 이 문장의 구체적인 실행이 결정되었다고 할 수 있습니다.

5) Executor

실행 계획을 선택한 후 MySQL은 실행을 시작할 준비가 됩니다. 먼저 실행 전에 사용자에게 권한이 있는지 확인합니다. 권한이 있으면 오류 메시지가 반환됩니다. , 엔진의 인터페이스를 호출하고 인터페이스 실행 결과를 반환합니다.

2 명령문 분석

2.1 쿼리 명령문

그런데, SQL 문은 어떻게 실행되나요? 실제로 우리 SQL은 두 가지 유형으로 나눌 수 있습니다. 하나는 쿼리이고 다른 하나는 업데이트(추가, 업데이트, 삭제)입니다. 먼저 다음과 같은 쿼리문을 분석해 보겠습니다.

select * from tb_student  A where A.age='18' and A.name=' 张三 ';

위 설명과 결합하여 이 문의 실행 과정을 분석해 보겠습니다.

먼저 해당 문에 권한이 있는지 확인하세요. 권한이 없으면 오류 메시지가 표시됩니다. 권한이 있는 경우 MySQL8.0 버전 이전에는 메모리에 결과가 있는지 여부를 쿼리하기 위해 이 sql 문을 키로 사용하여 캐시를 먼저 쿼리했습니다. , 다음 단계로 진행하세요.

분석기를 통해 어휘 분석을 수행하고 sql 문의 핵심 요소를 추출합니다. 예를 들어 위 명령문은 쿼리할 테이블 이름이 tb_student 입니다. 쿼리 조건은 다음과 같습니다. 이 테이블의 ID='1'입니다. 그런 다음 키워드가 올바른지 등 SQL 문에 구문 오류가 있는지 확인합니다. 문제가 없으면 다음 단계로 진행합니다.

다음 단계는 옵티마이저가 실행 계획을 결정하는 것입니다. 위의 SQL 문에는 두 가지 실행 계획이 있을 수 있습니다.

  a.先查询学生表中姓名为“张三”的学生,然后判断是否年龄是 18。
  b.先找出学生中年龄 18 岁的学生,然后再查询姓名为“张三”的学生。

그런 다음 옵티마이저는 자체 최적화 알고리즘에 따라 실행 효율성이 가장 좋은 계획을 선택합니다. 때로는 그것이 반드시 최고는 아닙니다). 그런 다음 실행 계획을 확인한 후 실행을 시작할 준비가 된 것입니다.

권한 확인을 수행합니다. 권한이 없으면 오류 메시지가 반환됩니다. 권한이 있으면 데이터베이스 엔진 인터페이스가 호출되고 엔진 실행 결과가 반환됩니다.

2.2 업데이트문

위는 쿼리SQL의 실행 과정인데, 업데이트문이 어떻게 실행되는지 살펴볼까요? SQL 문은 다음과 같습니다.

update tb_student A set A.age='19' where A.name=' 张三 ';

Zhang San의 나이를 수정해 보겠습니다. 나이 필드는 실제 데이터베이스에 설정되지 않습니다. 그렇지 않으면 담당 기술 담당자에게 패배할 것입니다. 실제로 각 명령문은 기본적으로 이전 쿼리의 프로세스를 따르지만 업데이트를 실행할 때 로그를 기록해야 합니다. 이는 MySQL 고유의 로그 모듈인 binlog(아카이브 로그) 을 소개하며, 모든 스토리지 엔진에서 사용할 수 있습니다. 일반적으로 사용되는 InnoDB 엔진에는 로그 모듈 redo 로그(redo log) 도 함께 제공됩니다. InnoDB 모드를 사용하여 이 명령문의 실행 프로세스를 살펴보겠습니다. 프로세스는 다음과 같습니다.

먼저 Zhang San의 데이터를 쿼리합니다. 캐시가 있으면 캐시도 사용됩니다.

그런 다음 쿼리문을 가져와서 age를 19로 변경한 다음 엔진 API 인터페이스를 호출하여 이 데이터 행을 씁니다. 이때 InnoDB 엔진은 데이터를 메모리에 저장하고 동시에 redo 로그를 기록합니다. 리두 로그는 준비 상태로 들어간 후 Executor에게 실행이 완료되었으며 언제든지 제출할 수 있음을 알립니다.

알림을 받은 Executor는 binlog를 기록한 다음 엔진 인터페이스를 호출하고 redo 로그를 제출 상태로 제출합니다.

업데이트가 완료되었습니다.

여기 일부 학생들은 왜 하나가 아닌 두 개의 로그 모듈을 사용해야 합니까?라고 분명히 묻습니다. MySQL의 내장 엔진은 MyISAM이지만 우리는 리두 로그가 InnoDB 엔진에만 고유하고 그렇지 않다는 것을 알고 있습니다. 이로 인해 충돌 방지 기능(데이터베이스가 비정상적으로 다시 시작되더라도 충돌 방지 기능, 이전에 제출된 기록은 손실되지 않음)이 부족하고 binlog 로그는 보관에만 사용할 수 있습니다.

로그 모듈 하나만 사용할 수 없다는 것은 아니지만 InnoDB 엔진은 Redo 로그를 통한 트랜잭션을 지원합니다. 그러면 일부 학생들은 두 개의 로그 모듈을 사용할 수 있지만 그렇게 복잡하지는 않은지 묻습니다. 왜 리두 로그가 준비 전 커밋 상태를 도입합니까? 여기서 우리는 왜 이것을 하는지 설명하기 위해 모순에 의한 증명을 사용합니다.

먼저 redo 로그를 작성하고 직접 제출한 다음 binlog를 작성합니다

. redo 로그를 작성한 후 시스템이 중단되고 binlog 로그가 작성되지 않는다고 가정합니다. 그런 다음 시스템을 다시 시작한 후 시스템이 복원됩니다. 하지만 당시 빙고는 이 데이터를 기록하지 않았다. 나중에 머신을 백업할 때 이 데이터는 손실되며 마스터-슬레이브 동기화에서도 이 데이터가 손실된다. .

먼저 binlog를 작성한 후 redo 로그를 작성합니다

binlog를 작성한 후 시스템이 비정상적으로 다시 시작되므로 시스템은 이 기록을 복원할 수 없지만 binlog에 기록이 있다고 가정해 보겠습니다. 이므로 위와 같은 이유로 데이터 불일치가 발생하게 됩니다.

리두 로그 2단계 제출 방법을 사용하면 빙로그 작성 후 리두 로그를 제출하면 위의 문제를 방지하고 데이터의 일관성을 보장할 수 있습니다. 그렇다면 문제는 극단적인 상황이 존재하는가 하는 것입니다. redo 로그가 pre-commit 상태이고, binglog가 작성되었다고 가정해보자. 이때 비정상적인 재시작이 발생하면 어떻게 될까?
MySQL의 처리 메커니즘에 따라 다릅니다.

리두 로그가 완료되었다고 판단되면 즉시 제출하세요.

리두 로그가 사전 제출만 되어 커밋 상태가 아닌 경우, 이때 빈로그 완료 여부를 판단하며, 완료되지 않은 경우에는 리두 로그를 제출하게 됩니다. 롤백되었습니다.

이것은 데이터 일관성 문제를 해결합니다.

세 가지 요약

MySQL은 크게 서버 계층과 엔진 계층으로 구분됩니다. 서버 계층에는 주로 커넥터, 쿼리 캐시, 분석기, 최적화 프로그램, 실행기 및 로그 모듈(binlog)이 포함됩니다. 공유, redolog는 InnoDB에서만 사용할 수 있습니다.

엔진 레이어는 플러그인 형태로 현재 주로 MyISAM, InnoDB, Memory 등이 포함되어 있습니다.

쿼리문의 실행 과정은 다음과 같습니다. 권한 확인(캐시 적중 시)--->쿼리 캐시--->Analyzer--->Optimizer--->권한 확인--->Executor-- - 》Engine

업데이트 문 실행 과정은 다음과 같습니다: 분석기----》권한 확인----》Executor---》Engine---redo log(준비 상태---》binlog---》 다시 실행 로그(커밋 상태) [관련 권장 사항: MySQL 튜토리얼]

위 내용은 MySQL에서 SQL 문은 어떻게 실행됩니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 segmentfault.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제