<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          MySQL 性能調(diào)優(yōu)的10個(gè)方法

          共 5712字,需瀏覽 12分鐘

           ·

          2021-03-20 07:31

          點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號(hào)”

          優(yōu)質(zhì)文章,第一時(shí)間送達(dá)

          ? 作者?|??claireyuancy

          來(lái)源 |??urlify.cn/JjIb2y

          MYSQL 應(yīng)該是最流行了 WEB 后端數(shù)據(jù)庫(kù)。WEB 開(kāi)發(fā)語(yǔ)言近期發(fā)展非常快,PHP, Ruby, Python, Java 各有特點(diǎn),盡管 NOSQL 近期越來(lái)越多的被提到,可是相信大部分架構(gòu)師還是會(huì)選擇 MYSQL 來(lái)做數(shù)據(jù)存儲(chǔ)。


          MYSQL 如此方便和穩(wěn)定。以至于我們?cè)陂_(kāi)發(fā) WEB 程序的時(shí)候非常少想到它。即使想到優(yōu)化也是程序級(jí)別的,比方。不要寫過(guò)于消耗資源的 SQL 語(yǔ)句。可是除此之外,在整個(gè)系統(tǒng)上仍然有非常多能夠優(yōu)化的地方。


          1. 選擇合適的存儲(chǔ)引擎: InnoDB

          除非你的數(shù)據(jù)表使用來(lái)做僅僅讀或者全文檢索 (相信如今提到全文檢索,沒(méi)人會(huì)用 MYSQL 了)。你應(yīng)該默認(rèn)選擇 InnoDB 。

          你自己在測(cè)試的時(shí)候可能會(huì)發(fā)現(xiàn) MyISAM 比 InnoDB 速度快。這是由于:MyISAM 僅僅緩存索引,而 InnoDB 緩存數(shù)據(jù)和索引,MyISAM 不支持事務(wù)。可是 假設(shè)你使用 innodb_flush_log_at_trx_commit = 2 能夠獲得接近的讀取性能 (相差百倍)?。


          1.1 怎樣將現(xiàn)有的 MyISAM 數(shù)據(jù)庫(kù)轉(zhuǎn)換為 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 為每一個(gè)表分別創(chuàng)建 InnoDB FILE:

          innodb_file_per_table=1

          這樣能夠保證 ibdata1 文件不會(huì)過(guò)大。失去控制。尤其是在運(yùn)行 mysqlcheck -o –all-databases 的時(shí)候。

          2. 保證從內(nèi)存中讀取數(shù)據(jù)。講數(shù)據(jù)保存在內(nèi)存中

          2.1?足夠大的 innodb_buffer_pool_size

          推薦將數(shù)據(jù)全然保存在 innodb_buffer_pool_size ,即按存儲(chǔ)量規(guī)劃 innodb_buffer_pool_size 的容量。這樣你能夠全然從內(nèi)存中讀取數(shù)據(jù)。最大限度降低磁盤操作。


          2.1.1 怎樣確定 innodb_buffer_pool_size 足夠大。數(shù)據(jù)是從內(nèi)存讀取而不是硬盤?

          方法 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)

          發(fā)現(xiàn) Innodb_buffer_pool_pages_free 為 0,則說(shuō)明 buffer pool 已經(jīng)被用光,須要增大?innodb_buffer_pool_size

          InnoDB 的其它幾個(gè)參數(shù):

          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 server上是否有足夠內(nèi)存用來(lái)規(guī)劃

          運(yùn)行 echo 1 > /proc/sys/vm/drop_caches 清除操作系統(tǒng)的文件緩存。能夠看到真正的內(nèi)存使用量。

          2.2 數(shù)據(jù)預(yù)熱

          默認(rèn)情況,僅僅有某條數(shù)據(jù)被讀取一次,才會(huì)緩存在 innodb_buffer_pool。所以,數(shù)據(jù)庫(kù)剛剛啟動(dòng),須要進(jìn)行數(shù)據(jù)預(yù)熱,將磁盤上的全部數(shù)據(jù)緩存到內(nèi)存中。

          數(shù)據(jù)預(yù)熱能夠提高讀取速度。

          對(duì)于 InnoDB 數(shù)據(jù)庫(kù),能夠用下面方法,進(jìn)行數(shù)據(jù)預(yù)熱:

          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. 運(yùn)行

          mysql?-uroot?-AN?<?/root/MakeSelectQueriesToLoad.sql?>?/root/SelectQueriesToLoad.sql

          3. 每次重新啟動(dòng)數(shù)據(jù)庫(kù),或者整庫(kù)備份前須要預(yù)熱的時(shí)候運(yùn)行:

          mysql?-uroot?<?/root/SelectQueriesToLoad.sql?>?/dev/null?2>&1

          2.3 不要讓數(shù)據(jù)存到 SWAP 中

          假設(shè)是專用 MYSQL server。能夠禁用 SWAP,假設(shè)是共享server,確定 innodb_buffer_pool_size 足夠大。或者使用固定的內(nèi)存空間做緩存,使用 memlock 指令。


          3. 定期優(yōu)化重建數(shù)據(jù)庫(kù)

          mysqlcheck -o –all-databases 會(huì)讓 ibdata1 不斷增大。真正的優(yōu)化僅僅有重建數(shù)據(jù)表結(jié)構(gòu):

          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

          可是須要注意假設(shè)用 1G 的 innodb_log_file_size 。假如server當(dāng)機(jī)。須要 10 分鐘來(lái)恢復(fù)。


          推薦 innodb_log_file_size 設(shè)置為 0.25 * innodb_buffer_pool_size

          4.2 innodb_flush_log_at_trx_commit

          這個(gè)選項(xiàng)和寫磁盤操作密切相關(guān):

          innodb_flush_log_at_trx_commit = 1 則每次改動(dòng)寫入磁盤
          innodb_flush_log_at_trx_commit = 0/2 每秒寫入磁盤

          假設(shè)你的應(yīng)用不涉及非常高的安全性 (金融系統(tǒng)),或者基礎(chǔ)架構(gòu)足夠安全,或者 事務(wù)都非常小,都能夠用?0 或者 2 來(lái)減少磁盤操作。


          4.3 避免雙寫入緩沖

          innodb_flush_method=O_DIRECT

          5. 提高磁盤讀寫速度

          RAID0?尤其是在使用 EC2 這樣的虛擬磁盤 (EBS) 的時(shí)候,使用軟 RAID0?很重要。

          6. 充分使用索引

          6.1 查看現(xiàn)有表結(jié)構(gòu)和索引

          SHOW?CREATE?TABLE?db1.tb1/G

          6.2 加入必要的索引

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

          索引的加入須要依據(jù)查詢來(lái)確定。比方通過(guò)慢查詢?nèi)罩净蛘卟樵內(nèi)罩?或者通過(guò) EXPLAIN 命令分析查詢。

          ADD?UNIQUE?INDEX
          ADD?INDEX
          6.2.1 比方,優(yōu)化用戶驗(yàn)證表:

          加入索引

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

          每次重新啟動(dòng)server進(jìn)行數(shù)據(jù)預(yù)熱

          echo?“select?username,password?from?users;”?>?/var/lib/mysql/upcache.sql

          加入啟動(dòng)腳本到 my.cnf

          [mysqld]
          init-file=/var/lib/mysql/upcache.sql
          6.2.2 使用自己主動(dòng)加索引的框架或者自己主動(dòng)拆分表結(jié)構(gòu)的框架

          比方。Rails 這種框架。會(huì)自己主動(dòng)加入索引。Drupal 這種框架會(huì)自己主動(dòng)拆分表結(jié)構(gòu)。

          會(huì)在你開(kāi)發(fā)的初期指明正確的方向。所以,經(jīng)驗(yàn)不太豐富的人一開(kāi)始就追求從 0 開(kāi)始構(gòu)建,實(shí)際是不好的做法。


          7. 分析查詢?nèi)罩竞吐樵內(nèi)罩?/strong>

          記錄全部查詢。這在用 ORM 系統(tǒng)或者生成查詢語(yǔ)句的系統(tǒng)非常實(shí)用。

          log=/var/log/mysql.log

          注意不要在生產(chǎn)環(huán)境用。否則會(huì)占滿你的磁盤空間。


          記錄運(yùn)行時(shí)間超過(guò) 1 秒的查詢:

          long_query_time=1
          log-slow-queries=/var/log/mysql/log-slow-queries.log

          8. 激進(jìn)的方法。使用內(nèi)存磁盤

          如今基礎(chǔ)設(shè)施的可靠性已經(jīng)非常高了,比方 EC2 差點(diǎn)兒不用操心server硬件當(dāng)機(jī)。并且內(nèi)存實(shí)在是廉價(jià)。非常easy買到幾十G內(nèi)存的server,能夠用內(nèi)存磁盤。定期備份到磁盤。


          將 MYSQL 文件夾遷移到 4G 的內(nèi)存磁盤

          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 仍然是最高效的索引之中的一個(gè),全部 MYSQL 仍然不會(huì)過(guò)時(shí)。


          用 HandlerSocket 跳過(guò) MYSQL 的 SQL 解析層。MYSQL 就真正變成了 NOSQL。

          10. 其它

          • 單條查詢最后添加 LIMIT 1,停止全表掃描。

          • 將非”索引”數(shù)據(jù)分離,比方將大篇文章分離存儲(chǔ),不影響其它自己主動(dòng)查詢。

          • 不用 MYSQL 內(nèi)置的函數(shù)。由于內(nèi)置函數(shù)不會(huì)建立查詢緩存。

          • PHP 的建立連接速度很快,全部能夠不用連接池。否則可能會(huì)造成超過(guò)連接數(shù)。當(dāng)然不用連接池 PHP 程序也可能將

          • 連接數(shù)占滿比方用了 @ignore_user_abort(TRUE);

          • 使用 IP 而不是域名做數(shù)據(jù)庫(kù)路徑。避免 DNS 解析問(wèn)題



          鋒哥最新SpringCloud分布式電商秒殺課程發(fā)布

          ??????

          ??長(zhǎng)按上方微信二維碼?2 秒





          感謝點(diǎn)贊支持下哈?7ec911f19081587f1636b8e00ac0d4f4.webp

          瀏覽 43
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  在线中文视频VA | 韩国一区二区在线视频 | 国产免费靠逼视频免费观看 | 五月婷丁香| 五月婷婷黄色 |