> 헤드라인 > MySQL은 어떻게 최적화되나요? 5가지 차원에서 성능 최적화에 대해 이야기해 보겠습니다.

MySQL은 어떻게 최적화되나요? 5가지 차원에서 성능 최적화에 대해 이야기해 보겠습니다.

青灯夜游
풀어 주다: 2022-06-22 10:23:17
앞으로
3781명이 탐색했습니다.

면접관이 다음과 같이 묻는 경우: 어떤 측면에서 MySQL 성능을 최적화하시겠습니까? 당신은 어떻게 대답하겠습니까?

소위 성능 최적화는 일반적으로 MySQL 쿼리 최적화를 목표로 합니다. 쿼리를 최적화하는 중이기 때문에 당연히 쿼리 작업이 어떤 링크를 거치는지 알아야 하고, 그런 다음 어떤 링크를 최적화할 수 있는지 고민해야 합니다.

쿼리 작업이 거쳐야 하는 기본 단계를 그림을 사용하여 보여줍니다.

MySQL은 어떻게 최적화되나요? 5가지 차원에서 성능 최적화에 대해 이야기해 보겠습니다.

다음은 MySQL 최적화를 위한 몇 가지 전략을 5가지 관점에서 소개합니다.

MySQL은 어떻게 최적화되나요? 5가지 차원에서 성능 최적화에 대해 이야기해 보겠습니다.

1. 연결 구성 최적화

연결 처리는 MySQL 클라이언트와 MySQL 서버 간의 관계의 첫 번째 단계입니다. 첫 번째 단계가 잘 진행되지 않으면 다음 이야기는 생략하겠습니다.

연결은 양측 모두의 문제이기 때문에 자연스럽게 서버 측과 클라이언트 측 모두에서 최적화합니다.

1.1 서버 구성

서버가 해야 할 일은 가능한 한 많은 클라이언트 연결을 허용하는 것입니다. 어쩌면 오류 1040: 너무 많은 연결이 발생했을 수도 있습니다. 서버의 마인드가 넓지 않고, 레이아웃이 너무 작기 때문이죠! error 1040: Too many connections的错误?就是服务端的胸怀不够宽广导致的,格局太小!

MySQL은 어떻게 최적화되나요? 5가지 차원에서 성능 최적화에 대해 이야기해 보겠습니다.

我们可以从两个方面解决连接数不够的问题:

1、增加可用连接数,修改环境变量max_connections,默认情况下服务端的最大连接数为151

mysql> show variables like 'max_connections';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_connections | 151   |
+-----------------+-------+
1 row in set (0.01 sec)
로그인 후 복사

2、及时释放不活动的连接,系统默认的客户端超时时间是28800秒(8小时),我们可以把这个值调小一点

mysql> show variables like 'wait_timeout';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wait_timeout  | 28800 |
+---------------+-------+
1 row in set (0.01 sec)
로그인 후 복사

MySQL有非常多的配置参数,并且大部分参数都提供了默认值,默认值是MySQL作者经过精心设计的,完全可以满足大部分情况的需求,不建议在不清楚参数含义的情况下贸然修改。

1.2 客户端优化

客户端能做的就是尽量减少和服务端建立连接的次数,已经建立的连接能凑合用就凑合用,别每次执行个SQL语句都创建个新连接,服务端和客户端的资源都吃不消啊。

解决的方案就是使用连接池来复用连接。

常见的数据库连接池有DBCPC3P0、阿里的DruidHikari,前两者用得很少了,后两者目前如日中天。

但是需要注意的是连接池并不是越大越好,比如Druid的默认最大连接池大小是8,Hikari默认最大连接池大小是10,盲目地加大连接池的大小,系统执行效率反而有可能降低。为什么?

对于每一个连接,服务端会创建一个单独的线程去处理,连接数越多,服务端创建的线程自然也就越多。而线程数超过CPU个数的情况下,CPU势必要通过分配时间片的方式进行线程的上下文切换,频繁的上下文切换会造成很大的性能开销。

Hikari官方给出了一个PostgreSQL数据库连接池大小的建议值公式,CPU核心数*2+1

MySQL은 어떻게 최적화되나요? 5가지 차원에서 성능 최적화에 대해 이야기해 보겠습니다.

us 연결 부족 문제는 다음 두 가지 측면에서 해결할 수 있습니다.

1 사용 가능한 연결 수를 늘리고 환경 변수 max_connections를 수정합니다. 기본적으로 서버의 최대 연결 수는 입니다. >151

mysql> show variables like 'slow_query%';
+---------------------+--------------------------------------+
| Variable_name       | Value                                |
+---------------------+--------------------------------------+
| slow_query_log      | OFF                                  |
| slow_query_log_file | /var/lib/mysql/9e74f9251f6c-slow.log |
+---------------------+--------------------------------------+
2 rows in set (0.00 sec)
로그인 후 복사
로그인 후 복사
2. 비활성 연결을 적시에 해제합니다. 시스템 기본 클라이언트 시간 제한은 28800초(8시간)입니다. 이 값을 더 작게 조정할 수 있습니다
mysql> show variables like '%long_query%';
+-----------------+-----------+
| Variable_name   | Value     |
+-----------------+-----------+
| long_query_time | 10.000000 |
+-----------------+-----------+
1 row in set (0.00 sec)
로그인 후 복사
로그인 후 복사

MySQL에는 많은 구성이 있습니다. 그리고 대부분의 매개변수는 기본값을 제공합니다. 기본값은 MySQL 작성자가 신중하게 설계했으며 대부분의 상황의 요구를 완전히 충족할 수 있으므로 매개변수의 의미를 모르고 함부로 수정하는 것은 권장되지 않습니다.

1.2 클라이언트 최적화

클라이언트가 할 수 있는 일은 서버에 대한 연결 수를 최소화하는 것입니다. 설정된 연결을 최대한 사용할 수 있습니다. . SQL 문을 실행할 때마다 새 연결을 만들지 마십시오. 서버와 클라이언트 모두의 리소스가 압도됩니다. MySQL은 어떻게 최적화되나요? 5가지 차원에서 성능 최적화에 대해 이야기해 보겠습니다.

해결책은

Connection Pool을 사용하여 연결을 재사용하는 것입니다.

일반적인 데이터베이스 연결 풀에는 DBCP, C3P0, Alibaba의 DruidHikari가 포함됩니다. 극소수이고 후자의 두 개는 현재 정점에 있습니다.

하지만 연결 풀이 클수록 좋습니다. 예를 들어 Druid의 기본 최대 연결 풀 크기는 8이고 Hikari의 기본 최대 연결 풀 크기입니다. 는 10입니다. Blindly 연결 풀의 크기를 과도하게 늘리면 시스템 실행 효율성이 저하될 수 있습니다. 왜? 🎜🎜각 연결에 대해 서버는 이를 처리하기 위해 별도의 스레드를 생성합니다. 연결이 많을수록 서버는 더 많은 스레드를 생성합니다. 스레드 수가 CPU 수를 초과하는 경우 CPU는 스레드의 컨텍스트 전환을 수행하기 위해 타임 슬라이스를 할당해야 합니다. 잦은 컨텍스트 전환으로 인해 많은 성능 오버헤드가 발생합니다. 🎜🎜Hikariofficial은 <코드>를 제공합니다 PostgreSQL데이터베이스 연결 풀 크기에 권장되는 값 공식은 CPU 코어 수*2+1입니다. 서버의 CPU 코어 수가 4개라고 가정하고 연결 풀을 9로 설정하면 됩니다. 이 공식은 다른 데이터베이스에도 어느 정도 적용 가능해 면접 때 자랑할 수 있다. 🎜🎜🎜2. 아키텍처 최적화 🎜🎜🎜🎜2.1 캐시 사용 🎜🎜🎜 이러한 쿼리는 대량의 데이터를 포함하거나 복잡한 쿼리(관련 테이블이 많거나 복잡한 계산)일 수 있습니다. ) 이로 인해 쿼리가 오랫동안 연결을 차지하게 됩니다. 🎜🎜이러한 데이터의 유효성이 특별히 강하지 않은 경우(일일 보고서와 같이 매 순간 변경되지 않는 경우) 이러한 데이터를 캐시 시스템에 넣을 수 있으며, 해당 데이터의 캐시 유효 기간 동안 캐시 시스템에서 직접 데이터베이스에서 데이터를 얻으면 데이터베이스에 대한 부담을 줄이고 쿼리 효율성을 높일 수 있습니다. 🎜🎜🎜🎜🎜🎜2.2 읽기 및 쓰기 분리(클러스터, 마스터-슬레이브 복제) 🎜🎜🎜프로젝트 초기에는 데이터베이스가 일반적으로 하나의 서버에서 실행되며 사용자의 모든 읽기 및 쓰기 요청이 직접적인 영향을 미칩니다. 이 데이터베이스 서버는 결국 단일 서버가 감당할 수 있는 동시성의 양이 제한되어 있습니다. 🎜

이 문제를 해결하기 위해 여러 데이터베이스 서버를 동시에 사용하고 그 중 하나를 마스터 노드라고 하는 팀 리더로 설정하고 나머지 노드를 라고 하는 팀 구성원으로 설정할 수 있습니다. 노예</ 코드>. 사용자는 <code>마스터 노드에만 데이터를 쓰고, 읽기 요청은 다양한 슬레이브 노드에 분산됩니다. 이 솔루션을 master节点,其余节点作为组员,叫做slave。用户写数据只往master节点写,而读的请求分摊到各个slave节点上。这个方案叫做读写分离。给组长加上组员组成的小团体起个名字,叫集群

MySQL은 어떻게 최적화되나요? 5가지 차원에서 성능 최적화에 대해 이야기해 보겠습니다.

注:很多开发者不满master-slave这种具有侵犯性的词汇(因为他们认为会联想到种族歧视、黑人奴隶等),所以发起了一项更名运动。

受此影响MySQL也会逐渐停用masterslave等术语,转而用sourcereplica替代,大家碰到的时候明白即可。

使用集群必然面临一个问题,就是多个节点之间怎么保持数据的一致性。毕竟写请求只往master节点上发送了,只有master节点的数据是最新数据,怎么把对master节点的写操作也同步到各个slave节点上呢?

主从复制技术来了!我在之前的文章中粗浅地介绍了一下binlog日志,我直接搬过来了。

binlog是实现MySQL主从复制功能的核心组件。master节点会将所有的写操作记录到binlog中,slave节点会有专门的I/O线程读取master节点的binlog,将写操作同步到当前所在的slave읽기-쓰기 분리

라고 합니다. 그룹 리더와 그룹 구성원으로 구성된 소그룹의 이름을

clusterMySQL은 어떻게 최적화되나요? 5가지 차원에서 성능 최적화에 대해 이야기해 보겠습니다.로 지정합니다.

MySQL은 어떻게 최적화되나요? 5가지 차원에서 성능 최적화에 대해 이야기해 보겠습니다.

참고: 많은 개발자들이 마스터-슬레이브라는 공격적인 용어에 불만을 품고(인종 차별, 흑인 노예 등과 연관될 것이라고 생각했기 때문에) 이름 변경 운동을 시작했습니다. 이 영향을 받아 MySQL도 마스터슬레이브와 같은 용어 사용을 점차 중단하고 대신 소스복제본<을 사용할 예정입니다. /code >Replacement, 모두가 마주치면 그냥 이해하세요. </p></blockquote><h3 data-id="heading-6">클러스터를 사용하면 필연적으로 여러 노드 간의 데이터 일관성을 유지하는 방법에 대한 문제에 직면하게 됩니다. 결국 쓰기 요청은 <code>master 노드로만 전송되고 master 노드의 데이터만 최신 데이터가 됩니다. >마스터 노드도 각 슬레이브 노드와 동기화하시겠습니까? 마스터-슬레이브 복제

기술이 등장했습니다! 이전 글에서 binlog 로그에 대해 간략하게 소개한 적이 있어서 직접 옮겼습니다.

binlog는 MySQL 마스터-슬레이브 복제 기능을 구현하는 핵심 구성요소입니다. master 노드는 모든 쓰기 작업을 binlog에 기록합니다. slave 노드에는 master</code의 binlog를 읽는 전용 I/O 스레드가 있습니다. > node. 현재 <code>slave 노드에 대한 쓰기 작업을 동기화합니다.

이 클러스터 아키텍처는 기본 데이터베이스 서버에 대한 부담을 줄이는 데 매우 좋은 효과가 있습니다. 그러나 비즈니스 데이터가 점점 증가함에 따라 특정 테이블의 데이터 양이 급격히 증가하면 단일 테이블의 쿼리 성능이 저하됩니다. 감소폭이 크게 줄어들고, 읽기-쓰기 분리로도 이 문제를 해결할 수 없습니다. 결국 모든 노드가 동일한 데이터를 저장하므로 당연히 모든 노드의 성능이 좋지 않습니다. .

MySQL은 어떻게 최적화되나요? 5가지 차원에서 성능 최적화에 대해 이야기해 보겠습니다.이때 단일 노드의 데이터를 여러 노드에 분산하여 저장할 수 있는 것이

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

입니다.

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

MySQL은 어떻게 최적화되나요? 5가지 차원에서 성능 최적화에 대해 이야기해 보겠습니다.

하위 데이터베이스 및 하위 테이블의 노드 의미는 비교적 광범위합니다. 데이터베이스가 노드로 사용되면 하위 데이터베이스입니다. 노드로 사용되는 경우 하위 테이블입니다.

샤딩이 수직 샤딩, 수직 샤딩, 수평 샤딩, 수평 샤딩으로 나누어진다는 것은 다들 아시겠지만, 개념이 기억나지 않을 때마다 이해를 돕기 위해 자세히 설명하겠습니다.

2.3.1 수직 하위 데이터베이스MySQL은 어떻게 최적화되나요? 5가지 차원에서 성능 최적화에 대해 이야기해 보겠습니다.

MySQL은 어떻게 최적화되나요? 5가지 차원에서 성능 최적화에 대해 이야기해 보겠습니다.하나의 데이터베이스를 기반으로 몇 개의 수직 컷을 만들고 비즈니스 로직에 따라 여러 데이터베이스로 분할하는 것이

수직 하위 데이터베이스

입니다.

2.3.2 세로 테이블 나누기

1MySQL은 어떻게 최적화되나요? 5가지 차원에서 성능 최적화에 대해 이야기해 보겠습니다.

세로 테이블 나누기는 하나의 테이블을 기준으로 세로 컷(또는 여러 컷)을 만들고, 테이블의 여러 문자를 여러 개로 나누는 것입니다. 작은 것 테이블, 이 작업은 특정 업무에 따라 판단해야합니다. 일반적으로 자주 사용하는 필드(핫 필드)는 하나의 테이블로 나누고, 자주 사용하지 않거나 즉시 사용하지 않는 필드(콜드 필드)는 하나의 테이블로 나눕니다. 쿼리 속도를 향상시키기 위한 테이블입니다.

1MySQL은 어떻게 최적화되나요? 5가지 차원에서 성능 최적화에 대해 이야기해 보겠습니다.

🎜🎜 위 사진을 예로 들어보세요. 일반적으로 상품 상세정보가 상대적으로 길어 상품 목록을 볼 때 바로 상품 상세정보를 표시할 필요가 없는 경우가 많습니다(일반적으로 상세정보 버튼을 클릭하면 표시됩니다). 그러나 제품의 더 중요한 정보(가격 등)가 표시됩니다. 이 비즈니스 로직에 따라 원래 제품 테이블을 수직 하위 테이블로 나누었습니다. 🎜🎜🎜2.3.3 수평 테이블 분할🎜🎜🎜특정 규칙(전문 용어로는 샤딩 규칙이라고 함)에 따라 단일 테이블의 데이터를 여러 데이터 테이블에 저장하고, 데이터 테이블에 수평으로 한 컷(또는 여러 컷)을 부여합니다. 지금은 🎜레벨 테이블🎜입니다. 🎜🎜🎜🎜🎜🎜🎜

2.3.4 水平分库

水平分库就是对单个数据库水平切一刀,往往伴随着水平分表。

1MySQL은 어떻게 최적화되나요? 5가지 차원에서 성능 최적화에 대해 이야기해 보겠습니다.

1MySQL은 어떻게 최적화되나요? 5가지 차원에서 성능 최적화에 대해 이야기해 보겠습니다.

2.3.5 总结

水平分,主要是为了解决存储的瓶颈;垂直分,主要是为了减轻并发压力。

2.4 消息队列削峰

通常情况下,用户的请求会直接访问数据库,如果同一时刻在线用户数量非常庞大,极有可能压垮数据库(参考明星出轨或公布恋情时微博的状态)。

这种情况下可以通过使用消息队列降低数据库的压力,不管同时有多少个用户请求,先存入消息队列,然后系统有条不紊地从消息队列中消费请求。

1MySQL은 어떻게 최적화되나요? 5가지 차원에서 성능 최적화에 대해 이야기해 보겠습니다.

3. 优化器——SQL分析与优化

处理完连接、优化完缓存等架构的事情,SQL查询语句来到了解析器和优化器的地盘了。在这一步如果出了任何问题,那就只能是SQL语句的问题了。

只要你的语法不出问题,解析器就不会有问题。此外,为了防止你写的SQL运行效率低,优化器会自动做一些优化,但如果实在是太烂,优化器也救不了你了,只能眼睁睁地看着你的SQL查询沦为慢查询

3.1 慢查询

慢查询就是执行地很慢的查询(这句话说得跟废话似的。。。),只有知道MySQL中有哪些慢查询我们才能针对性地进行优化。

因为开启慢查询日志是有性能代价的,因此MySQL默认是关闭慢查询日志功能,使用以下命令查看当前慢查询状态

mysql> show variables like &#39;slow_query%&#39;;
+---------------------+--------------------------------------+
| Variable_name       | Value                                |
+---------------------+--------------------------------------+
| slow_query_log      | OFF                                  |
| slow_query_log_file | /var/lib/mysql/9e74f9251f6c-slow.log |
+---------------------+--------------------------------------+
2 rows in set (0.00 sec)
로그인 후 복사
로그인 후 복사

slow_query_log表示当前慢查询日志是否开启,slow_query_log_file表示慢查询日志的保存位置。

除了上面两个变量,我们还需要确定“慢”的指标是什么,即执行超过多长时间才算是慢查询,默认是10S,如果改成0的话就是记录所有的SQL。

mysql> show variables like &#39;%long_query%&#39;;
+-----------------+-----------+
| Variable_name   | Value     |
+-----------------+-----------+
| long_query_time | 10.000000 |
+-----------------+-----------+
1 row in set (0.00 sec)
로그인 후 복사
로그인 후 복사

3.1.1 打开慢日志

有两种打开慢日志的方式

1、修改配置文件my.cnf

此种修改方式系统重启后依然有效

# 是否开启慢查询日志
slow_query_log=ON
# 
long_query_time=2
slow_query_log_file=/var/lib/mysql/slow.log
로그인 후 복사

2、动态修改参数(重启后失效)

mysql> set @@global.slow_query_log=1;
Query OK, 0 rows affected (0.06 sec)

mysql> set @@global.long_query_time=2;
Query OK, 0 rows affected (0.00 sec)
로그인 후 복사

3.1.2 慢日志分析

MySQL不仅为我们保存了慢日志文件,还为我们提供了慢日志查询的工具mysqldumpslow,为了演示这个工具,我们先构造一条慢查询:

mysql> SELECT sleep(5);
로그인 후 복사

然后我们查询用时最多的1条慢查询:

[root@iZ2zejfuakcnnq2pgqyzowZ ~]# mysqldumpslow -s t -t 1 -g &#39;select&#39; /var/lib/mysql/9e74f9251f6c-slow.log

Reading mysql slow query log from /var/lib/mysql/9e74f9251f6c-slow.log
Count: 1  Time=10.00s (10s)  Lock=0.00s (0s)  Rows=1.0 (1), root[root]@localhost
  SELECT sleep(N)
로그인 후 복사

其中,

  • Count:表示这个SQL执行的次数
  • Time:表示执行的时间,括号中的是累积时间
  • Locks:表示锁定的时间,括号中的是累积时间
  • Rows:表示返回的记录数,括号中的是累积数

更多关于mysqldumpslow的使用方式,可以查阅官方文档,或者执行mysqldumpslow --help寻求帮助。

3.2 查看运行中的线程

我们可以运行show full processlist查看MySQL中运行的所有线程,查看其状态和运行时间,找到不顺眼的,直接kill。

1MySQL은 어떻게 최적화되나요? 5가지 차원에서 성능 최적화에 대해 이야기해 보겠습니다.

其中,

  • Id:线程的唯一标志,可以使用Id杀死指定线程
  • User:启动这个线程的用户,普通账户只能查看自己的线程
  • Host:哪个ip和端口发起的连接
  • db:线程操作的数据库
  • Command:线程的命令
  • Time:操作持续时间,单位秒
  • State:线程的状态
  • Info:SQL语句的前100个字符

3.3 查看服务器运行状态

使用SHOW STATUS查看MySQL服务器的运行状态,有sessionglobal两种作用域,一般使用like+通配符进行过滤。

-- 查看select的次数
mysql> SHOW GLOBAL STATUS LIKE &#39;com_select&#39;;
+---------------+--------+
| Variable_name | Value  |
+---------------+--------+
| Com_select    | 168241 |
+---------------+--------+
1 row in set (0.05 sec)
로그인 후 복사

3.4 查看存储引擎运行信息

SHOW ENGINE用来展示存储引擎的当前运行信息,包括事务持有的表锁、行锁信息;事务的锁等待情况;线程信号量等待;文件IO请求;Buffer pool统计信息等等数据。

例如:

SHOW ENGINE INNODB STATUS;
로그인 후 복사

上面这条语句可以展示innodb存储引擎的当前运行的各种信息,大家可以据此找到MySQL当前的问题,限于篇幅不在此意义说明其中信息的含义,大家只要知道MySQL提供了这样一个监控工具就行了,等到需要的时候再来用就好。

3.5 EXPLAIN执行计划

通过慢查询日志我们可以知道哪些SQL语句执行慢了,可是为什么慢?慢在哪里呢?

MySQL提供了一个执行计划的查询命令EXPLAIN,通过此命令我们可以查看SQL执行的计划,所谓执行计划就是:优化器会不会优化我们自己书写的SQL语句(比如外连接改内连接查询,子查询优化为连接查询...)、优化器针对此条SQL的执行对哪些索引进行了成本估算,并最终决定采用哪个索引(或者最终选择不用索引,而是全表扫描)、优化器对单表执行的策略是什么,等等等等。

EXPLAIN在MySQL5.6.3之后也可以针对UPDATE、DELETE和INSERT语句进行分析,但是通常情况下我们还是用在SELECT查询上。

这篇文章主要是从宏观上多个角度介绍MySQL的优化策略,因此这里不详细说明EXPLAIN的细节,之后单独成篇。

3.6 SQL与索引优化

3.6.1 SQL优化

SQL优化指的是SQL本身语法没有问题,但是有实现相同目的的更好的写法。比如:

  • 使用小表驱动大表;用join改写子查询;or改成union
  • 连接查询中,尽量减少驱动表的扇出(记录数),访问被驱动表的成本要尽量低,尽量在被驱动表的连接列上建立索引,降低访问成本;被驱动表的连接列最好是该表的主键或者是唯一二级索引列,这样被驱动表的成本会降到更低
  • 大偏移量的limit,先过滤再排序

针对最后一条举个简单的例子,下面两条语句能实现同样的目的,但是第二条的执行效率比第一条执行效率要高得多(存储引擎使用的是InnoDB),大家感受一下:

-- 1. 大偏移量的查询
mysql> SELECT * FROM user_innodb LIMIT 9000000,10;
Empty set (8.18 sec)

-- 2.先过滤ID(因为ID使用的是索引),再limit
mysql> SELECT * FROM user_innodb WHERE id > 9000000 LIMIT 10;
Empty set (0.02 sec)
로그인 후 복사

3.6.2 索引优化

为慢查询创建适当的索引是个非常常见并且非常有效的方法,但是索引是否会被高效使用又是另一门学问了。

推荐阅读:《如何用好MySQL索引?你必须了解这些事!》,感兴趣的读者可以看一下。
//m.sbmmt.com/mysql-tutorials-493147.html

4. 存储引擎与表结构

4.1 选择存储引擎

一般情况下,我们会选择MySQL默认的存储引擎存储引擎InnoDB,但是当对数据库性能要求精益求精的时候,存储引擎的选择也成为一个关键的影响因素。

建议根据不同的业务选择不同的存储引擎,例如:

  • 查询操作、插入操作多的业务表,推荐使用MyISAM
  • 临时表使用Memory
  • 并发数量大、更新多的业务选择使用InnoDB
  • 不知道选啥直接默认。

4.2 优化字段

字段优化的最终原则是:使用可以正确存储数据的最小的数据类型

4.2.1 整数类型

MySQL提供了6种整数类型,分别是

  • tinyint
  • smallint
  • mediumint
  • int
  • integer
  • bigint

不同的存储类型的最大存储范围不同,占用的存储的空间自然也不同。

例如,是否被删除的标识,建议选用tinyint,而不是bigint

4.2.2 字符类型

你是不是直接把所有字符串的字段都设置为varchar格式了?甚至怕不够,还会直接设置成varchar(1024)的长度?

如果不确定字段的长度,肯定是要选择varchar,但是varchar需要额外的空间来记录该字段目前占用的长度;因此如果字段的长度是固定的,尽量选用char,这会给你节约不少的内存空间。

4.2.3 Null이 아닌

Null이 아닌 필드는 최대한 NOT NULL로 설정하고 기본값을 제공하거나 대신 특수 값을 사용해야 합니다. NULL. NOT NULL,并提供默认值,或者使用特殊值代替NULL

因为NULL类型的存储和优化都会存在性能不佳的问题,具体原因在这里就不展开了。

4.2.4 不要用外键、触发器和视图功能

这也是「阿里巴巴开发手册」中提到的原则。原因有三个:

  • 降低了可读性,检查代码的同时还得查看数据库的代码;

  • 把计算的工作交给程序,数据库只做好存储的工作,并把这件事情做好;

  • 数据的完整性校验的工作应该由开发者完成,而不是依赖于外键,一旦用了外键,你会发现测试的时候随便删点垃圾数据都变得异常艰难。

4.2.5 图片、音频、视频存储

不要直接存储大文件,而是要存储大文件的访问地址。

4.2.6 大字段拆分和数据冗余

大字段拆分其实就是前面说过的垂直分表,把不常用的字段或者数据量较大的字段拆分出去,避免列数过多和数据量过大,尤其是习惯编写SELECT *

NULL 유형의 저장 및 최적화에는 성능 저하 문제가 있으므로 여기서는 구체적인 이유를 논의하지 않습니다.

4.2.4 외래키, 트리거, 뷰 기능을 사용하지 마세요

이것도 "알리바바 개발 매뉴얼"에서도 언급한 원칙입니다. 세 가지 이유가 있습니다.

가독성이 떨어지고 동시에 데이터베이스의 코드를 확인해야 합니다.

  • 계산 작업은 프로그램에 맡기고 데이터베이스는 저장 작업만 수행합니다.

  • 데이터 무결성 확인 작업은 외래 키에 의존하는 대신 개발자가 완료해야 합니다. 일단 외래 키를 사용하면 테스트 중에 정크 데이터를 삭제하기가 매우 어려워집니다. .
  • 4.2.5 사진, 오디오, 비디오 저장

  • 대용량 파일을 직접 저장하지 말고, 대용량 파일의 접근 주소를 저장하세요.

    4.2.6 대규모 필드 분할 및 데이터 중복


대형 필드 분할

사실 앞서 언급한 수직 테이블 분할은 자주 사용되지 않는 필드나 너무 많은 열과 너무 큰 데이터 볼륨을 피하기 위해 데이터 볼륨이 큰 필드를 분할하십시오. 특히 SELECT * 작성에 익숙하다면 많은 열과 큰 데이터 볼륨으로 인해 발생하는 문제가 제거됩니다. 심각하게 증폭되었습니다!

필드 중복성

원칙적으로 데이터베이스 설계 패러다임을 따르지는 않지만 빠른 검색에 매우 도움이 됩니다. 예를 들어 계약 테이블에 고객 ID를 저장하는 경우 고객 이름을 중복하여 저장할 수 있으므로 쿼리 시 고객 ID를 기준으로 사용자 이름을 얻을 필요가 없습니다. 따라서 비즈니스 로직에 대해 어느 정도 중복성을 만드는 것이 더 나은 최적화 기술이기도 합니다. 🎜🎜🎜5. 비즈니스 최적화🎜🎜🎜 엄밀히 말하면 비즈니스 최적화는 더 이상 MySQL 튜닝의 수단이 아니지만, 비즈니스 최적화는 데이터베이스 액세스 부담을 매우 효과적으로 줄일 수 있습니다. 다음은 Taobao의 몇 가지 간단한 예입니다. 몇 가지 아이디어를 드리고자 합니다: 🎜🎜🎜🎜과거에는 더블 11의 밤에 구매와 구매의 패턴이 시작되었습니다. 최근 몇 년 동안 더블 11의 사전 판매 전선이 점점 길어져 절반 이상을 시작했습니다. , 다양한 예금 빨간 봉투 모델이 등장하고 있습니다. 이 방법을 🎜사전 판매 전환🎜이라고 합니다. 이를 통해 고객 서비스 요청을 전환할 수 있으며, 일괄적으로 주문하기 위해 Double Eleven의 이른 아침까지 기다릴 필요가 없습니다. 🎜🎜🎜🎜Double Eleven의 이른 아침에는 그날 이외의 주문을 확인하고 싶을 수도 있습니다. 그러나 Alipay에서도 쿼리가 실패합니다. 이것은 🎜다운그레이드 전략🎜으로, 현재 핵심 비즈니스를 보장하기 위해 중요하지 않은 서비스에 대한 컴퓨팅 리소스를 수집합니다. 🎜🎜🎜🎜Alipay는 Double Eleven Huabei 중에 이를 사용할 것을 적극 권장합니다. 은행 카드 결제 대신 결제 방식을 사용합니다. 소프트웨어의 끈적거림을 개선하기 위한 고려 사항도 있지만 실제로 Yu'ebao에서 사용하는 Alibaba 내부 서버를 사용하면 액세스 속도가 빠른 반면, 은행 카드를 사용하려면 전화를 걸어야 합니다. 이에 비해 은행 인터페이스는 작업 속도가 훨씬 느립니다. 🎜🎜🎜🎜🎜MySQL 최적화 요약은 여기서 끝납니다. 언급되지 않은 세부 사항이 많아서 이 기사가 완벽하지 않다는 느낌이 듭니다. 하지만, 세부적으로 다 적기에는 지식 포인트가 너무 많습니다. 나중에 적어보겠습니다. 🎜🎜【관련 추천: 🎜mysql 비디오 튜토리얼🎜】🎜
관련 라벨:
원천:juejin.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿