<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國際加速解決方案。 廣告
                ## 背景 6.5號,小編在 Aliyun 的論壇中發現一位開發者提的一個問題,說 RDS 發現了一個超級大BUG,嚇的小編一身冷汗 = =!! 趕緊來看看,背景是一個RDS用戶創建了一張表,在一個都是NULL值的非索引字段上進行了排序并分頁,用戶發現第二頁和第一頁的數據有重復,然后以為是NULL值的問題,把這個字段都更新成相同的值,發現問題照舊。詳細的信息可以登錄阿里云的[官方論壇查看](http://bbs.aliyun.com/read/248026.html "發現超級大BUG,你遇到了嗎?開發者必看!")。 小編進行了嘗試,確實如此,并且5.5的版本和5.6的版本行為不一致,所以,必須要查明原因。 ## 原因調查 在MySQL 5.6的版本上,優化器在遇到order by limit語句的時候,做了一個優化,即使用了priority queue。參考偽代碼: ~~~ while (get_next_sortkey()) { if (using priority queue) push sort key into queue else { if (no free space in sort_keys buffers) { sort sort_keys buffer; dump sorted sequence to 'tempfile'; dump BUFFPEK describing sequence location into 'buffpek_pointers'; } put sort key into 'sort_keys'; } } if (sort_keys has some elements && dumped at least once) sort-dump-dump as above; else don't sort, leave sort_keys array to be sorted by caller. ~~~ 使用 priority queue 的目的,就是在不能使用索引有序性的時候,如果要排序,并且使用了limit n,那么只需要在排序的過程中,保留n條記錄即可,這樣雖然不能解決所有記錄都需要排序的開銷,但是只需要 sort buffer 少量的內存就可以完成排序。 之所以5.6出現了第二頁數據重復的問題,是因為 priority queue 使用了堆排序的排序方法,而堆排序是一個不穩定的排序方法,也就是相同的值可能排序出來的結果和讀出來的數據順序不一致。 5.5 沒有這個優化,所以也就不會出現這個問題。 ## 解決方法 1\. 索引排序字段 之前的月報中,我們討論過三星索引的設計,其中第二條就是利用索引的有序性,如果用戶在字段添加上索引,就直接按照索引的有序性進行讀取并分頁,從而可以規避遇到的這個問題。 2\. 正確理解分頁 還是要正確理解分頁,分頁是建立在排序的基礎上,進行了數量范圍分割。排序是數據庫提供的功能,而分頁卻是衍生的出來的應用需求。在MySQL和Oracle的官方文檔中提供了limit n和rownum < n的方法,但卻沒有明確的定義分頁這個概念。還有重要的一點,雖然上面的解決方法可以緩解用戶的這個問題,但按照用戶的理解,依然還有問題:比如,這個表插入比較頻繁,用戶查詢的時候,在read-committed的隔離級別下,第一頁和第二頁仍然會有重合。 分頁一直都有這個問題,我們看分頁常用的場景:1)早期的論壇 2)個人交易記錄。這些場景都對數據分頁都沒有非常高的準確性要求。 ## 究竟是不是BUG 究竟歸于bug問題還是用戶使用理解上的問題? 小編覺得應該分開看待這個問題,如果是排序的問題,那就算是BUG,如果是分頁的這個問題,那它確實完成了order by的功能,也完成了limit n功能,那就不能說它是BUG,分頁就純粹變成了用戶理解的問題了。 ## 用戶在使用數據庫的時候常見的一些問題: 1\. 不加order by的時候的排序問題 用戶在使用Oracle或MySQL的時候,發現MySQL總是有序的,Oracle卻很混亂,這個主要是因為Oracle是堆表,MySQL是索引聚簇表的原因。所以沒有order by的時候,數據庫并不保證記錄返回的順序性,并且不保證每次返回都一致的。 2\. 分頁問題 分頁重復的問題,就如前面所描述的,分頁是在數據庫提供的排序功能的基礎上,衍生出來的應用需求,數據庫并不保證分頁的重復問題。 3\. NULL值和空串問題 不同的數據庫對于NULL值和空串的理解和處理是不一樣的,比如Oracle NULL和NULL值是無法比較的,既不是相等也不是不相等,是未知的。而對于空串,在插入的時候,MySQL是一個字符串長度為0的空串,而Oracle則直接進行NULL值處理。
                  <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>

                              哎呀哎呀视频在线观看