1. <wbr id="cnjas"><legend id="cnjas"></legend></wbr>

          Linux培訓
          達內IT學院

          400-111-8989

          MYSQL調優和使用必讀

          • 發布:佚名
          • 來源:網絡
          • 時間:2015-07-27 11:07

          MYSQL 應該是最流行了 WEB 后端數據庫。WEB 開發語言最近發展很快,PHP, Ruby, Python, Java 各有特點,雖然 NOSQL 最近越來越多的被提到,但是相信大部分架構師還是會選擇 MYSQL 來做數據存儲。

          MYSQL 如此方便和穩定,以至于我們在開發 WEB 程序的時候很少想到它。即使想到優化也是程序級別的,比如,不要寫過于消耗資源的 SQL 語句。但是除此之外,在整個系統上仍然有很多可以優化的地方。

          1. 選擇合適的存儲引擎: InnoDB

          除非你的數據表使用來做只讀或者全文檢索 (相信現在提到全文檢索,沒人會用 MYSQL 了),你應該默認選擇 InnoDB 。

          你自己在測試的時候可能會發現 MyISAM 比 InnoDB 速度快,這是因為: MyISAM 只緩存索引,而 InnoDB 緩存數據和索引,MyISAM 不支持事務。但是 如果你使用 innodb_flush_log_at_trx_commit = 2 可以獲得接近的讀取性能 (相差百倍) 。

          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 FILE:

          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 '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)

          發現 Innodb_buffer_pool_pages_free 為 0,則說明 buffer pool 已經被用光,需要增大 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('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. 執行

          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 添加必要的索引

          ADD UNIQUE INDEX
          ADD INDEX

          索引是提高查詢速度的唯一方法,比如搜索引擎用的倒排索引是一樣的原理。

          索引的添加需要根據查詢來確定,比如通過慢查詢日志或者查詢日志,或者通過 EXPLAIN 命令分析查詢。

          6.2.1 比如,優化用戶驗證表:

          添加索引

          ALTER TABLE users ADD UNIQUE INDEX username_ndx (username);
          ALTER TABLE users ADD UNIQUE INDEX username_password_ndx (username,password);

          每次重啟服務器進行數據預熱

          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 幾乎不用擔心服務器硬件當機。而且內存實在是便宜,很容易買到幾十G內存的服務器,可以用內存磁盤,定期備份到磁盤。

          將 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 解析問題

          11. 結束

          你會發現優化后,數據庫的性能提高幾倍到幾百倍。所以 MYSQL 基本還是可以適用大部分場景的應用的。優化現有系統的成本比系統重構或者遷移到 NOSQL 低很多

          預約申請免費試聽課

          填寫下面表單即可預約申請免費試聽!怕錢不夠?可就業掙錢后再付學費! 怕學不會?助教全程陪讀,隨時解惑!擔心就業?一地學習,可全國推薦就業!

          上一篇:Linux系統內核有待提高的七個領域
          下一篇:進程和線程關系及區別

          安裝完MySQL后必須調整的10項配置

          • 掃碼領取資料

            回復關鍵字:視頻資料

            免費領取 達內課程視頻學習資料

          • 視頻學習QQ群

            添加QQ群:1143617948

            免費領取達內課程視頻學習資料

          Copyright ? 2021 Tedu.cn All Rights Reserved 京ICP備08000853號-56 京公網安備 11010802029508號 達內時代科技集團有限公司 版權所有

          選擇城市和中心
          黑龍江省

          吉林省

          河北省

          湖南省

          貴州省

          云南省

          廣西省

          海南省

          欧美做爰视频免费播放_做暖全过程免费的视频_性爱免费视频 百度 好搜 搜狗
          <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <文本链> <文本链> <文本链> <文本链> <文本链> <文本链>