Empfohlenes Tutorial: MySQL-Tutorial
1. Wählen Sie die entsprechende Speicher-Engine: InnoDB
Es sei denn, Ihre Datentabelle wird zum Nur-Lesen- oder Volltextabruf verwendet (ich glaube, niemand wird MYSQL verwenden, wenn es darum geht bis hin zur Volltextsuche) ). Sie sollten standardmäßig InnoDB auswählen.
Wenn Sie es selbst testen, stellen Sie möglicherweise fest, dass MyISAM schneller als InnoDB ist. Dies liegt daran, dass MyISAM nur Indizes zwischenspeichert, während InnoDB Daten und Indizes zwischenspeichert und MyISAM keine Transaktionen unterstützt. Aber vorausgesetzt, Sie verwenden innodb_flush_log_at_trx_commit = 2, können Sie eine nahezu gute Leseleistung erzielen (einen Hundertfachen Unterschied).
1.1 So konvertieren Sie eine vorhandene MyISAM-Datenbank in 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 Für jede InnoDB-DATEI erstellen für jede Tabelle:
innodb_file_per_table=1
Dadurch kann sichergestellt werden, dass die ibdata1-Datei nicht zu groß wird. Die Kontrolle verlieren. Besonders beim Ausführen von mysqlcheck -o –all-databases.
2. Garantiert Daten aus dem Speicher lesen. Apropos Daten, die im Speicher gespeichert werden
2.1 Eine ausreichend große innodb_buffer_pool_size
Es wird empfohlen, sie zu speichern Alle Daten in innodb_buffer_pool_size, dh die Planung der Kapazität von innodb_buffer_pool_size entsprechend der Speichermenge. Auf diese Weise können Sie die Daten vollständig aus dem Speicher lesen. Minimieren Sie Festplattenvorgänge.
2.1.1 So ermitteln Sie, ob innodb_buffer_pool_size groß genug ist. Werden die Daten aus dem Speicher statt von der Festplatte gelesen?
Methode 1
mysql> SHOW GLOBAL STATUS LIKE 'innodb_buffer_pool_pages_%'; +----------------------------------+--------+ | 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)
Es wurde festgestellt, dass Innodb_buffer_pool_pages_free 0 ist, was bedeutet, dass der Pufferpool verwendet wurde up. Es ist notwendig, innodb_buffer_pool_size zu erhöhen
Mehrere andere Parameter von InnoDB:
innodb_additional_mem_pool_size = 1/200 of buffer_pool innodb_max_dirty_pages_pct 80%
Methode 2
Oder verwenden Sie den Befehl iostat -d -x -k 1, um den Betrieb der Festplatte zu überprüfen.
2.1.2 Ob auf dem Server genügend Speicher für die Planung vorhanden ist
Führen Sie echo 1 > aus /sys/vm/drop_caches Löscht den Dateicache des Betriebssystems. Möglichkeit, die tatsächliche Speichernutzung zu sehen.
2.2 Datenerwärmung
Standardmäßig werden Daten nur dann zwischengespeichert, wenn sie einmal eingelesen werden innodb_buffer_pool. Daher wurde die Datenbank gerade erst gestartet und muss die Daten aufwärmen und alle Daten auf der Festplatte im Speicher zwischenspeichern.
Das Vorwärmen der Daten kann die Lesegeschwindigkeit erhöhen.
Für die InnoDB-Datenbank können Sie die folgende Methode zum Aufwärmen der Daten verwenden:
1. Speichern Sie das folgende Skript als MakeSelectQueriesToLoad.sql
SELECT DISTINCT CONCAT('SELECT ',ndxcollist,' FROM ',db,'.',tb, ' ORDER BY ',ndxcollist,';') 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='InnoDB' ) B USING (table_schema,table_name) WHERE B.table_schema NOT IN ('information_schema','mysql') 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. Führen Sie
mysql -uroot -AN < /root/MakeSelectQueriesToLoad.sql > /root/SelectQueriesToLoad.sql
aus. 3. Führen Sie dies jedes Mal aus, wenn Sie die Datenbank neu starten oder wenn Sie sich aufwärmen müssen Bevor Sie die gesamte Datenbank sichern:
mysql -uroot < /root/SelectQueriesToLoad.sql > /dev/null 2>&1
2.3 Das Speichern von Daten in SWAP nicht zulassen
Vorausgesetzt, es handelt sich um einen dedizierten MYSQL-Server. SWAP kann deaktiviert werden, vorausgesetzt, es handelt sich um einen gemeinsam genutzten Server, und stellen Sie sicher, dass innodb_buffer_pool_size groß genug ist. Oder verwenden Sie einen festen Speicherplatz zum Caching und verwenden Sie die Memlock-Anweisung.
3. Optimieren und erneuern Sie die Datenbank
mysqlcheck - o –all-databases sorgt dafür, dass ibdata1 weiter wächst. Die eigentliche Optimierung umfasst nur den Neuaufbau der Datentabellenstruktur:
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. Reduzieren Sie die Schreibvorgänge auf der Festplatte
4.1 Verwenden Sie einen ausreichend großen Schreibcache innodb_log_file_size
Es ist jedoch zu beachten, dass davon ausgegangen wird, dass 1 GB innodb_log_file_size verwendet wird. Wenn der Server abstürzt. Die Wiederherstellung dauert 10 Minuten.
Empfohlene innodb_log_file_size ist auf 0,25 * innodb_buffer_pool_size eingestellt
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 解析问题
Das obige ist der detaillierte Inhalt vonMehrere Methoden zur MySQL-Optimierung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!