欧美一区二区三区,国内熟女精品熟女A片视频小说,日本av网,小鲜肉男男GAY做受XXX网站

數據庫存儲引擎innodb會自動排序

林雅南2年前25瀏覽0評論

數據庫存儲引擎innodb會自動排序?

今天在review代碼查看SQL語句時突然對沒有指定排序方式的SQL語句返回怎樣的排序結構感興趣!在某些場景中返回結果中的元素到底是按照什么順序以什么字段排序的將直接影響到整個業務是否正確。例如myBatis中語句如下:

<select id="get_by_id" resultMap="App" parameterClass="java.lang.Long"> select <include refid="fileds"/> from table_a where id = #id# and type = 2 and state != 0 </select>

排查問題

那么到底MySQL在沒有指定排序字段以及排序順序時是按照什么規則排序呢?最早猜測是按照主鍵排序,即在table_a表中按照id字段進行降序排列。那么到底是否正確呢?為了驗證猜測,在本地通過Navicat8對這個猜測進行了驗證:SELECT * FROM test_a查詢結果:

發現查詢結果并沒有按照猜測的方式進行排序,并且查詢結果沒有任何規律可循。這樣看來如果按照上述的方式處理業務是很有可能出現問題的。仔細想了一下,這個問題應該和數據庫存儲引擎有關系,然后再網上查閱了一下這個問題,發現各種說法都有,但是初步驗證了這個問題確實和數據庫存儲引擎有關系,不同的數據庫引擎對默認排序的處理是不一致的,但是都沒有統一的答案,因此決定測試一下常用的兩種數據庫引擎:InnoDB以及MyISAM,簡單介紹一下兩個數據庫引擎:

簡單點說就是InnoDB的優點是支持事務,支持非鎖定讀,行鎖設計,以及全文索引,MyISAM的優點是操作速度快,不支持事務以及行鎖,是MySQL默認的存儲引擎。

在本地創建兩個表a,b,兩個表唯一的區別在于a使用MyISAM作為存儲引擎,b使用InnoDB作為存儲引擎,然后兩個表均忘表中插入100條數據。在插入數據后對量表分別進行無排序的全表查詢結果如下:

(表a:MyISAM)(表b:InnoDB)

從查詢結果上來看兩個表是否都按照id進行升序排列,與table_a表查詢結果順序完全不一致,查看一下開發環境的table_a表的存儲引擎為MyISAM,與表a一致,但是查詢結果卻沒有任何相似的地方,是什么影響了table_a表的查詢結果呢?難道是各種增刪改查操作?因為兩個相同引擎的表都進行無排序的全表查詢唯一區別是表a沒有進行過任何的更新刪除操作,表table_a進行過大量的增刪改查操作,于是對表a以及表b均模擬進行大量的增刪改查操作,然后再次進行查詢:

(表a:MyISAM)(表b:InnoDB)

發現表a查詢結果出現了無序情況,表象與表table_a一致,而表b查詢結果仍然按照id進行升序排列。

因此初步判定在MySQL中,如果使用MyISAM作為存儲引擎,那么在進行默認排序的查詢時,如果表沒有進行過任何的更新刪除等操作,那么查詢結果將按照出入順序進行升序排列,但是如果對表進行了更新刪除等操作后,查詢結果將是無序的;如果使用InnoDB作為存儲引擎,那么在存在主鍵的情況下,查詢結果將按照主鍵進行排序。因此在編寫默認排序的SQL語句的時候,一定要注意使用的存儲引擎,不同的存儲引擎可能產生的查詢結果完全不一致。

猜想原因:應該和兩種存儲引擎采用的存儲結構有關系,在查閱資料以后發現InnoDB采用的是聚簇索引表,而MyISAM采用的是無序的堆表結構。最后在MySQL的官方網頁上發現了對該問題的一個描述:

SELECT * FROM tbl -- this will do a "table scan". If the table has never had any DELETEs/REPLACEs/UPDATEs, the records will happen to be in the insertion order, hence what you observed. If you had done the same statement with an InnoDB table, they would have been delivered in PRIMARY KEY order, not INSERT order. Again, this is an artifact of the underlying implementation, not something to depend on.大概意思是說在使用默認的存儲引擎(MyISAM)進行全表查詢時,會進行表掃描,如果表沒有進行過刪除、替換以及更新操作,那么查詢結果將按照插入順序進行排序,如果在使用InnoDB作為存儲引擎執行相同的操作時,查詢結果將按照主鍵進行排序,而不是按照插入順序進行排序的。