> 데이터 베이스 > MySQL 튜토리얼 > MySQL 최적화의 여러 가지 방법

MySQL 최적화의 여러 가지 방법

angryTom
풀어 주다: 2019-07-20 15:23:09
원래의
11992명이 탐색했습니다.

MySQL 최적화의 여러 가지 방법

추천 튜토리얼: MySQL 튜토리얼

1 적절한 스토리지 엔진을 선택하세요: InnoDB

데이터 테이블이 읽기 전용이나 전체 텍스트 검색용으로 사용되지 않는 한(I 지금 믿으십시오. 전체 텍스트 검색에 관해서는 MYSQL을 사용하는 방법을 아는 사람이 없습니다. 기본적으로 InnoDB를 선택해야 합니다.

직접 테스트해 보면 MyISAM이 InnoDB보다 빠르다는 것을 알 수 있습니다. 그 이유는 MyISAM은 인덱스만 캐시하는 반면 InnoDB는 데이터와 인덱스를 캐시하고 MyISAM은 트랜잭션을 지원하지 않기 때문입니다. 그러나 innodb_flush_log_at_trx_commit = 2를 사용한다고 가정하면 가까운 읽기 성능을 얻을 수 있습니다(100배 차이).

1.1 기존 MyISAM 데이터베이스를 InnoDB로 변환하는 방법:

mysql -u [USER_NAME] -p -e "SHOW TABLES IN [DATABASE_NAME];" | tail -n +2 | xargs -I '{}' echo "ALTER TABLE {} ENGINE=InnoDB;" > alter_table.sql
perl -p -i -e 's/(search_[a-z_]+ ENGINE=)InnoDB//1MyISAM/g' alter_table.sql
mysql -u [USER_NAME] -p [DATABASE_NAME] < alter_table.sql
로그인 후 복사

1.2 각 테이블에 대한 InnoDB 파일 생성:

innodb_file_per_table=1
로그인 후 복사

 이렇게 하면 ibdata1 파일이 너무 크다. 통제력 상실. 특히 mysqlcheck -o –all-databases를 실행할 때.

2. 메모리에서 데이터 읽기가 보장됩니다. 메모리에 저장되는 데이터에 대해 이야기하기

2.1 충분히 큰 innodb_buffer_pool_size

모든 데이터를 innodb_buffer_pool_size에 저장하는 것이 좋습니다. 즉, 저장량에 따라 innodb_buffer_pool_size의 용량을 계획하는 것이 좋습니다. 이렇게 하면 메모리에서 데이터 전체를 읽을 수 있습니다. 디스크 작업을 최소화합니다.

2.1.1 innodb_buffer_pool_size를 결정하는 방법이 충분히 큽니다. 하드 드라이브가 아닌 메모리에서 데이터를 읽고 있습니까?

방법 1

mysql> SHOW GLOBAL STATUS LIKE &#39;innodb_buffer_pool_pages_%&#39;;
+----------------------------------+--------+
| Variable_name                    | Value  |
+----------------------------------+--------+
| Innodb_buffer_pool_pages_data    | 129037 |
| Innodb_buffer_pool_pages_dirty   | 362    |
| Innodb_buffer_pool_pages_flushed | 9998   |
| Innodb_buffer_pool_pages_free    | 0      |  !!!!!!!!
| Innodb_buffer_pool_pages_misc    | 2035   |
| Innodb_buffer_pool_pages_total   | 131072 |
+----------------------------------+--------+
6 rows in set (0.00 sec)
로그인 후 복사

Innodb_buffer_pool_pages_free가 0임을 확인했습니다. 이는 버퍼 풀이 모두 사용되었음을 의미하며 innodb_buffer_pool_size

InnoDB의 다른 매개변수를 늘려야 함을 의미합니다.

innodb_additional_mem_pool_size = 1/200 of buffer_pool
innodb_max_dirty_pages_pct 80%
로그인 후 복사

방법 2

 또는 iostat -d -x -k 1 명령을 사용하여 하드디스크의 동작을 확인합니다.

2.1.2 서버에 계획을 위한 메모리가 충분한지 여부

  echo 1 > /proc/sys/vm/drop_caches를 실행하여 운영 체제의 파일 캐시를 지웁니다. 실제 메모리 사용량을 확인하는 기능.

2.2 데이터 워밍

 기본적으로 특정 데이터 조각만 한 번 읽은 후 innodb_buffer_pool에 캐시됩니다. 따라서 데이터베이스가 방금 시작되었으며 데이터를 준비하고 디스크의 모든 데이터를 메모리에 캐시해야 합니다.

  데이터를 예열하면 읽기 속도가 빨라질 수 있습니다.

 InnoDB 데이터베이스의 경우 다음 방법을 사용하여 데이터를 워밍업할 수 있습니다:

 1. 다음 스크립트를 MakeSelectQueriesToLoad.sql

SELECT DISTINCT
    CONCAT(&#39;SELECT &#39;,ndxcollist,&#39; FROM &#39;,db,&#39;.&#39;,tb,
    &#39; ORDER BY &#39;,ndxcollist,&#39;;&#39;) SelectQueryToLoadCache
    FROM
    (
        SELECT
            engine,table_schema db,table_name tb,
            index_name,GROUP_CONCAT(column_name ORDER BY seq_in_index) ndxcollist
        FROM
        (
            SELECT
                B.engine,A.table_schema,A.table_name,
                A.index_name,A.column_name,A.seq_in_index
            FROM
                information_schema.statistics A INNER JOIN
                (
                    SELECT engine,table_schema,table_name
                    FROM information_schema.tables WHERE
                    engine=&#39;InnoDB&#39;
                ) B USING (table_schema,table_name)
            WHERE B.table_schema NOT IN (&#39;information_schema&#39;,&#39;mysql&#39;)
            ORDER BY table_schema,table_name,index_name,seq_in_index
        ) A
        GROUP BY table_schema,table_name,index_name
    ) AA
ORDER BY db,tb
;
로그인 후 복사

 2. 실행

mysql -uroot -AN < /root/MakeSelectQueriesToLoad.sql > /root/SelectQueriesToLoad.sql
로그인 후 복사

 3. 매번 데이터베이스를 다시 시작하거나 전체 데이터베이스를 백업하기 전에 워밍업이 필요할 때 실행하십시오.

mysql -uroot < /root/SelectQueriesToLoad.sql > /dev/null 2>&1
로그인 후 복사

2.3 데이터를 SWAP에 저장하지 마십시오

전용 MYSQL 서버라고 가정합니다. . 공유 서버라고 가정하고 SWAP를 비활성화할 수 있으며 innodb_buffer_pool_size가 충분히 큰지 확인하세요. 또는 캐싱을 위해 고정된 메모리 공간을 사용하고 memlock 명령어를 사용하세요.

3. 정기적으로 데이터베이스를 최적화하고 재구축합니다.

Mysqlcheck -o –all-databases로 인해 ibdata1이 계속해서 증가합니다. 실제 최적화는 데이터 테이블 구조를 재구축하는 것뿐입니다:

CREATE TABLE mydb.mytablenew LIKE mydb.mytable;
INSERT INTO mydb.mytablenew SELECT * FROM mydb.mytable;
ALTER TABLE mydb.mytable RENAME mydb.mytablezap;
ALTER TABLE mydb.mytablenew RENAME mydb.mytable;
DROP TABLE mydb.mytablezap;
로그인 후 복사

4. 디스크 쓰기 작업 줄이기

4.1 충분히 큰 쓰기 캐시 사용 innodb_log_file_size

그러나 다음과 같이 가정해야 합니다. 1G는 innodb_log_file_size 를 사용합니다. 서버가 충돌하는 경우. 회복하는데 10분 정도 소요됩니다.

 innodb_log_file_size를 0.25*innodb_buffer_pool_size

4.2 innodb_flush_log_at_trx_commit

로 설정하는 것이 좋습니다.

  这个选项和写磁盘操作密切相关:

  innodb_flush_log_at_trx_commit = 1 则每次改动写入磁盘

  innodb_flush_log_at_trx_commit = 0/2 每秒写入磁盘

  假设你的应用不涉及非常高的安全性 (金融系统),或者基础架构足够安全,或者 事务都非常小,都能够用 0 或者 2 来减少磁盘操作。

4.3 避免双写入缓冲

innodb_flush_method=O_DIRECT
로그인 후 복사

5. 提高磁盘读写速度

  RAID0 尤其是在使用 EC2 这样的虚拟磁盘 (EBS) 的时候,使用软 RAID0 很重要。

6. 充分使用索引

6.1 查看现有表结构和索引

SHOW CREATE TABLE db1.tb1/G
로그인 후 복사

6.2 加入必要的索引

  索引是提高查询速度的唯一方法。比方搜索引擎用的倒排索引是一样的原理。

  索引的加入须要依据查询来确定。比方通过慢查询日志或者查询日志,或者通过 EXPLAIN 命令分析查询。

ADD UNIQUE INDEX
ADD INDEX
로그인 후 복사

6.2.1 比方,优化用户验证表:

  加入索引

ALTER TABLE users ADD UNIQUE INDEX username_ndx (username);
ALTER TABLE users ADD UNIQUE INDEX username_password_ndx (username,password);
로그인 후 복사

  每次重新启动server进行数据预热

echo “select username,password from users;” > /var/lib/mysql/upcache.sql
로그인 후 복사

  加入启动脚本到 my.cnf

[mysqld]
init-file=/var/lib/mysql/upcache.sql
로그인 후 복사

6.2.2 使用自己主动加索引的框架或者自己主动拆分表结构的框架

  比方。Rails 这种框架。会自己主动加入索引。Drupal 这种框架会自己主动拆分表结构。

  会在你开发的初期指明正确的方向。所以,经验不太丰富的人一開始就追求从 0 開始构建,实际是不好的做法。

7. 分析查询日志和慢查询日志

  记录全部查询。这在用 ORM 系统或者生成查询语句的系统非常实用。

log=/var/log/mysql.log
로그인 후 복사

  注意不要在生产环境用。否则会占满你的磁盘空间。

  记录运行时间超过 1 秒的查询:

long_query_time=1
log-slow-queries=/var/log/mysql/log-slow-queries.log
로그인 후 복사

8. 激进的方法。使用内存磁盘

  如今基础设施的可靠性已经非常高了,比方 EC2 差点儿不用操心server硬件当机。并且内存实在是廉价。非常easy买到几十G内存的server,能够用内存磁盘。定期备份到磁盘。

  将 MYSQL 文件夹迁移到 4G 的内存磁盘

mkdir -p /mnt/ramdisk
sudo mount -t tmpfs -o size=4000M tmpfs /mnt/ramdisk/
mv /var/lib/mysql /mnt/ramdisk/mysql
ln -s /tmp/ramdisk/mysql /var/lib/mysql
chown mysql:mysql mysql
로그인 후 복사

9. 用 NOSQL 的方式使用 MYSQL

  B-TREE 仍然是最高效的索引之中的一个,全部 MYSQL 仍然不会过时。

  用 HandlerSocket 跳过 MYSQL 的 SQL 解析层。MYSQL 就真正变成了 NOSQL。

10. 其它

  ●单条查询最后添加 LIMIT 1,停止全表扫描。

  ●将非”索引”数据分离,比方将大篇文章分离存储,不影响其它自己主动查询。

  ●不用 MYSQL 内置的函数。由于内置函数不会建立查询缓存。

  ●PHP 的建立连接速度很快,全部能够不用连接池。否则可能会造成超过连接数。当然不用连接池 PHP 程序也可能将

  ●连接数占满比方用了 @ignore_user_abort(TRUE);

  ●使用 IP 而不是域名做数据库路径。避免 DNS 解析问题

위 내용은 MySQL 최적화의 여러 가지 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿