<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ## 背景 目前,IO 仍然是數據庫的性能殺手,為了提高 IO 利用率和吞吐量,不同的數據庫都設計了不同的方法,本文就介紹下 InnoDB 提供的預讀(read-ahead)功能,以及 Oracle 提供的多塊讀(multiblock-read)功能,并進行一些對比。 ### InnoDB read-ahead InnoDB 提供了兩種預讀的方式,一種是 Linear read ahead,由參數`innodb_read_ahead_threshold`控制,當你連續讀取一個 extent 的 threshold 個 page 的時候,會觸發下一個 extent 64個page的預讀。另外一種是Random read-ahead,由參數`innodb_random_read_ahead`控制,當你連續讀取設定的數量的page后,會觸發讀取這個extent的剩余page。 InnoDB 的預讀功能是使用后臺線程異步完成的。InnoDB啟動了`innodb_read_io_threads`個后臺線程,來完成IO request,并且可以使用Native AIO,在你的環境中如果安裝了libaio,在MySQL實例啟動的時候,查看系統日志:`InnoDB: Using Linux native AIO`?表明 InnoDB 已經使用Native AIO了。在Linear read ahead觸發的時候,InnoDB通過`io_submit()`提交了下一個extent的64個pages的IO request,并由一個read IO thread完成。 ### Oracle multiblock-read 當你要對堆表進行全表掃描,并需要大量IO的時候,通常在 session 級別設置`db_file_multiblock_read_count`,這樣 Oracle 會在讀取堆表結構的數據塊的時候,一次IO讀取多個數據塊,大大減少了IO的次數。但這里一次合并IO請求的數據塊,必須不能在buffer pool中,否則會分割IO請求。不過,在針對大表的匯總分析查找中,設置`db_file_multiblock_read_count`的效果是非常明顯的。不過也要注意,不要在系統級別上設置過大的`db_file_multiblock_read_count`, 會造成buffer cache flooding。 ## 場景分析 下面我們看兩個非常典型的場景: 1\. 高并發,小IO的情況 在高并發的場景下,sql響應時間主要取決于同步IO請求的時間,而InnoDB的預讀通常不會觸發,就算觸發,更多的是預熱(warmup)的效果,并不會對系統帶來非常大的收益,對rt的影響也非常小。 而Oracle如果設置了`db_file_multiblock_read_count`,在這樣的場景下,有可能會適得其反,因為一次同步IO請求的時間增加了。 所以在這樣的場景下,InnoDB的read-ahead和Oracle的multiblock-read并不會帶來太多的收益。我們看另外一個場景。 2\. 低并發,高IO吞吐 通常,我們可能想在業務低峰期,對線上數據進行匯總查詢。這時,希望能夠完全使用主機的資源來完成sql的查詢,在使用全表掃描的時候,InnoDB會觸發read-ahead,每次提前異步讀取下一個extent的page,加快讀取的速度。 Oracle使用`db_file_multiblock_read_count`,一次IO讀取多個block,提高讀取的吞吐量。 ## 問題 為什么在聚集查詢的時候,Oracle的效果會比InnoDB要好? 這個問題,在針對機械盤的情況,又回到了 IOPS 和 throughput 的討論上去了。InnoDB的read-ahead,在觸發的時候,針對下一個extent,對每一個page提交了異步IO請求,也就是增加了IO request次數,雖然Native AIO和disk會有針對性合并IO,但仍然非常有限,而Oracle每次提交合并多個連續數據塊的IO請求,能夠更好利用disk的吞吐能力。 所以,InnoDB在針對aggregation類型的查詢的時候,想要完全使用IO的吞吐能力,相比較Oracle的multiblock-read,會偏弱一點。 ## 優化方法 針對InnoDB的機制,我們可以嘗試幾種優化方法: 1. 在session級別,提供可設置預讀的觸發條件,并使用多個后臺線程來完成異步IO請求。因為沒有減少小IO請求,作者嘗試了這種方法,收益甚小; 2. 獨立一個buffer pool,專門進行多塊讀,針對next extent,一次讀取到buffer pool中,這種方式就和Oracle的multiblock-read比較類似了; 3. 終極優化方法,就是使用并行查詢,Oracle在全表掃描的時候,使用`/* parallel */`?hint方法啟動多個進程完成查詢,InnoDB的聚簇索引結構,需要邏輯分片,針對每一個分片啟動一個線程完成查詢。 讀者如果有興趣,可以進行一些嘗試。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看