<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
硬體條件限制:
程式設計方面:
沒有索引或未使用到索引表資料量過大(可採用分批查詢,減少單次查詢資料量)返回不必要的行/列鎖/死鎖(例如:給表新增欄位導致鎖表,此時執行sql語句會被阻塞,直至表解鎖)
慢查詢紀錄檔:MySQL提供的一種紀錄檔記錄,它用來記錄在MySQL中響應時間超過閥值(long_query_time,單位:秒)的SQL語句。參考mysql慢查詢紀錄檔輪轉_MySQL慢查詢紀錄檔實操
MySQL官方對索引的定義為:索引(Index)是幫助MySQL高效獲取資料的資料結構。我們可以簡單理解為:快速查詢排好序的一種資料結構(好比一本書的目錄)。Mysql索引主要有兩種結構:B+Tree索引和Hash索引。我們平常所說的索引,如果沒有特別指明,一般都是指B樹結構組織的索引(B+Tree索引)。索引如圖所示:
最外層淺藍色磁碟塊1裡有資料17、35(深藍色)和指標P1、P2、P3(黃色)。P1指標表示小於17的磁碟塊,P2是在17-35之間,P3指向大於35的磁碟塊。真實資料存在於葉子節點也就是最底下的一層3、5、9、10、13......非葉子節點不儲存真實的資料,只儲存指引搜尋方向的資料項,如17、35。
查詢過程:例如搜尋28資料項,首先載入磁碟塊1到記憶體中,發生一次I/O,用二分查詢確定在P2指標。接著發現28在26和30之間,通過P2指標的地址載入磁碟塊3到記憶體,發生第二次I/O。用同樣的方式找到磁碟塊8,發生第三次I/O。
真實的情況是,上面3層的B+Tree可以表示上百萬的資料,上百萬的資料只發生了三次I/O而不是上百萬次I/O,時間提升是巨大的。
前文鋪墊完成,進入實操部分,先來插入測試需要的資料:
CREATE TABLE `user_info` ( `id` BIGINT(20) NOT NULL AUTO_INCREMENT, `name` VARCHAR(50) NOT NULL DEFAULT '', `age` INT(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `name_index` (`name`) )ENGINE = InnoDB DEFAULT CHARSET = utf8; INSERT INTO user_info (name, age) VALUES ('xys', 20); INSERT INTO user_info (name, age) VALUES ('a', 21); INSERT INTO user_info (name, age) VALUES ('b', 23); INSERT INTO user_info (name, age) VALUES ('c', 50); INSERT INTO user_info (name, age) VALUES ('d', 15); INSERT INTO user_info (name, age) VALUES ('e', 20); INSERT INTO user_info (name, age) VALUES ('f', 21); INSERT INTO user_info (name, age) VALUES ('g', 23); INSERT INTO user_info (name, age) VALUES ('h', 50); INSERT INTO user_info (name, age) VALUES ('i', 15); CREATE TABLE `order_info` ( `id` BIGINT(20) NOT NULL AUTO_INCREMENT, `user_id` BIGINT(20) DEFAULT NULL, `product_name` VARCHAR(50) NOT NULL DEFAULT '', `productor` VARCHAR(30) DEFAULT NULL, PRIMARY KEY (`id`), KEY `user_product_detail_index` (`user_id`, `product_name`, `productor`) )ENGINE = InnoDB DEFAULT CHARSET = utf8; INSERT INTO order_info (user_id, product_name, productor) VALUES (1, 'p1', 'WHH'); INSERT INTO order_info (user_id, product_name, productor) VALUES (1, 'p2', 'WL'); INSERT INTO order_info (user_id, product_name, productor) VALUES (1, 'p1', 'DX'); INSERT INTO order_info (user_id, product_name, productor) VALUES (2, 'p1', 'WHH'); INSERT INTO order_info (user_id, product_name, productor) VALUES (2, 'p5', 'WL'); INSERT INTO order_info (user_id, product_name, productor) VALUES (3, 'p3', 'MA'); INSERT INTO order_info (user_id, product_name, productor) VALUES (4, 'p1', 'WHH'); INSERT INTO order_info (user_id, product_name, productor) VALUES (6, 'p1', 'WHH'); INSERT INTO order_info (user_id, product_name, productor) VALUES (9, 'p8', 'TE');
初體驗,執行Explain的效果:
索引使用情況在possible_keys、key和key_len三列,接下來我們先從左到右依次講解。
--id相同,執行順序由上而下 explain select u.*,o.* from user_info u,order_info o where u.id=o.user_id;
--id不同,值越大越先被執行 explain select * from user_info where id = (select user_id from order_info where product_name ='p8');
可以看id的執行範例,總共有以下幾種型別:
table表示查詢涉及的表或衍生的表:
explain select tt.* from (select u.* from user_info u,order_info o where u.id=o.user_id and u.id=1) tt
id為1的<derived2>的表示id為2的u和o表衍生出來的。
type 欄位比較重要,它提供了判斷查詢是否高效的重要依據。通過 type 欄位,我們判斷此次查詢是 全表掃描 還是 索引掃描 等。
type 常用的取值有:
通常來說, 不同的 type 型別的效能關係如下:
ALL < index < range ~ index_merge < ref < eq_ref < const < system
ALL 型別因為是全表掃描, 因此在相同的查詢條件下,它是速度最慢的。而 index 型別的查詢雖然不是全表掃描,但是它掃描了所有的索引,因此比 ALL 型別的稍快。後面的幾種型別都是利用了索引來查詢資料,因此可以過濾部分或大部分資料,因此查詢效率就比較高了。
它表示 mysql 在查詢時,可能使用到的索引。 注意,即使有些索引在 possible_keys 中出現,但是並不表示此索引會真正地被 mysql 使用到。 mysql 在查詢時具體使用了哪些索引,由 key 欄位決定。
此欄位是 mysql 在當前查詢時真正用到的索引。比如請客吃飯的場景,possible_keys是應到多少人,key是實到多少人。
當我們沒有建立索引時:
explain select o.* from order_info o where o.product_name= 'p1' and o.productor='whh'; create index idx_name_productor on order_info(productor); drop index idx_name_productor on order_info;
建立複合索引後再查詢:
表示查詢優化器使用了索引的位元組數,這個欄位可以評估組合索引是否完全被使用。
這一列顯示了在key列記錄的索引中,表查詢值所用到的列或常數,常見的有:const(常數),func,NULL,欄位名(例:film.id)。前文的type屬性裡也有ref,注意區別。
rows 也是一個重要的欄位,mysql 查詢優化器根據統計資訊,估算 sql 要查詢到結果集需要掃描讀取的資料行數,這個值非常直觀的顯示 sql 效率好壞, 原則上 rows 越少越好。可以對比key中的例子,一個沒建立索引前,rows是9,建立索引後,rows是4。
具體可參考文章:mysql or走索引加索引及慢查詢的作用
explain 中的很多額外的資訊會在 extra 欄位顯示, 常見的有以下幾種內容:
explain select u.*,o.* from user_info u LEFT JOIN order_info o on u.id = o.user_id;
執行結果,type有ALL,並且沒有索引:
開始優化,在關聯列上建立索引,明顯看到type列的ALL變成ref,並且用到了索引,rows也從掃描9行變成了1行:
這裡面一般有個規律是:左連線時,索引加在右表關聯欄位上(由於上述範例為LEFT JOIN,所以索引加在右表order_info上)。相反的,右連線索引加在左表關聯欄位上。
索引雖然能非常高效的提高查詢速度,但卻會降低表的更新速度。實際上索引也是一張表,該表儲存了主鍵與索引欄位,並指向實體表的記錄,所以索引列也是要佔用空間的。
到此這篇關於MySQL索引介紹及優化方式的文章就介紹到這了,更多相關MySQL索引 內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45