国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

「MySQL系列」索引設計原則、索引失效場景、Limit 、Order By、Group By 等常見場景優化

數據庫 MySQL
MySQL在存儲數據之外,數據庫系統還維護者滿足特定查找算法的 數據結構,這些數據結構以某種方式引用(指向)數據, 這樣就 可以在這些數據結構上實現高級查找算法,這種數據結構就是索引。

 一 索引使用

1.1 概述

1. 定義

索引幫助MySQL高效獲取數據的數據結構(按照一定規則)。

2. 定義解釋

MySQL在存儲數據之外,數據庫系統還維護者滿足特定查找算法的 數據結構,這些數據結構以某種方式引用(指向)數據, 這樣就 可以在這些數據結構上實現高級查找算法,這種數據結構就是索引。

3. 優缺點

優點 提高數據檢索效率,降低數據庫IO成本。通過索引對數據進行排序降低數據排序成本,降低CPU消耗。缺點 實際上索引也是一張表,該表中保存了主鍵與索引字段,并指向實體類的記錄,所以索引列也是要占用空間的。更新表時,MySQL 不僅要保存數據,還要保存一下索引文件每次更新添加了索引列的字段,都會調整因為更新所帶來的鍵值變化后的索引信息。

1.2 索引結構(InnoDB)

MySQL數據庫中默認的存儲引擎InnoDB的索引結構為B+樹,而根據 葉子節點的內存存儲不同,索引類型分為主鍵索引和非主鍵索引。

1. 主鍵索引(聚簇索引)

主鍵索引的葉子節點存儲的是整行數據,其結構如下:


2. 非主鍵索引(二級索引或輔助索引)

而非主鍵索引的葉子節點內容存儲時的主鍵的值,其結構如下: 

1.3 索引使用規則

沒有建立索引,執行計劃如下


建立索引

  1. create index idx_seller_name_status_address on tb_seller(name, status, seller); 

1. 全值匹配,對索引所有列都制定具體值

  1. explain select * from tb_seller where name='小米科技' and status='1' and 
  2. address='北京市'

 

2. 最左前綴法制


違背最左法則,索引失效


如果符合最左法則,但是出現跳躍某一列,只有最左列索引生效:


3. 范圍查詢右邊的列,不能使用索引


根據前面的兩個字段name,status查詢是走索引的,但是最后一 個條件address 沒有用到索引。

4. 索引列上進行運算操作,索引失效


5. 字符串不加單引號,造成索引失效


由于,在查詢是,沒有對字符串加單引號,MySQL的查詢優化器, 會自動的進行類型轉換,造成索引失效。

6. 用or分割開的條件

示例,name字段是索引列 , 而createtime不是索引列,中間是 or進行連接是不走索引的 :

  1. explain select * from tb_seller where name='黑馬程序員' or createtime = '2088-01-01 12:00:00'\G; 

 

7. 以%開頭的Like模糊查詢,索引失效。


解決方案


8. 如果MySQL評估使用索引比全表更慢,則不使用索引


9. is NULL,is NOT NULL有時索引失效。


10. in,not in有時索引失效


11. 盡量使用覆蓋索引,避免select

盡量使用覆蓋索引(只訪問索引的查詢(索引列完全包含查詢列)),減少select。


如果查詢列,超出索引列,也會降低性能。

  1. using index :使用覆蓋索引的時候就會出現 
  2. using where:在查找使用索引的情況下,需要回表去查詢所需的數據 
  3. using index condition:查找使用了索引,但是需要回表查詢數據 
  4. using index ; using where:查找使用了索引,但是需要的數據都在索引列中能找到,所以不需要 
  5. 回表查詢數據 

1.4 索引設計原則

索引的設計可以遵循一些已有的原則,創建索引的時候請盡量考 慮符合這些原則,便于提升索引的使用效率,更高效的使用索引。

  1. 對查詢頻次較高,且數據量比較大的表建立索引。 
  2.  
  3. 索引字段的選擇,最佳候選列應當從where子句的條件中提取,如 
  4. where子句中的組合比較多,那么應當挑選最常用、過濾效果最 
  5. 好的列的組合。 
  6.  
  7. 使用唯一索引,區分度越高,使用索引的效率越高。 
  8.  
  9. 索引可以有效的提升查詢數據的效率,但索引數量不是多多益 
  10. 善,索引越多,維護索引的代價自然也就水漲船高。對于插入、 
  11. 更新、刪除等DML操作比較頻繁的表來說,索引過多,會引入相當 
  12. 高的維護代價,降低DML操作的效率,增加相應操作的時間消耗。 
  13. 另外索引過多的話,MySQL也會犯選擇困難病,雖然最終仍然會找 
  14. 到一個可用的索引,但無疑提高了選擇的代價。 
  15.  
  16. 使用短索引,索引創建之后也是使用硬盤來存儲的,因此提升索 
  17. 引訪問的I/O效率,也可以提升總體的訪問效率。假如構成索引的 
  18. 字段總長度比較短,那么在給定大小的存儲塊內可以存儲更多的 
  19. 索引值,相應的可以有效的提升MySQL訪問索引的I/O效率。 
  20.  
  21. 利用最左前綴,N個列組合而成的組合索引,那么相當于是創建了 
  22. N個索引,如果查詢時where子句中使用了組成該索引的前幾個字 
  23. 段,那么這條查詢SQL可以利用組合索引來提升查詢效率。 

二 常見SQL優化

2.1 數據庫準備

1. sql

  1. CREATE TABLE `emp` ( 
  2.   `id` int(11) NOT NULL AUTO_INCREMENT, 
  3.   `namevarchar(100) NOT NULL
  4.   `age` int(3) NOT NULL
  5.   `salary` int(11) DEFAULT NULL
  6.   PRIMARY KEY (`id`) 
  7. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 
  8. insert into `emp` (`id`, `name`, `age`, `salary`) values('1','Tom','25','2300'); 
  9. insert into `emp` (`id`, `name`, `age`, `salary`) 
  10. values('2','Jerry','30','3500'); 
  11. insert into `emp` (`id`, `name`, `age`, `salary`) 
  12. values('3','Luci','25','2800'); 
  13. insert into `emp` (`id`, `name`, `age`, `salary`) values('4','Jay','36','3500'); 
  14. insert into `emp` (`id`, `name`, `age`, `salary`) 
  15. values('5','Tom2','21','2200'); 
  16. insert into `emp` (`id`, `name`, `age`, `salary`) 
  17. values('6','Jerry2','31','3300'); 
  18. insert into `emp` (`id`, `name`, `age`, `salary`) 
  19. values('7','Luci2','26','2700'); 
  20. insert into `emp` (`id`, `name`, `age`, `salary`) 
  21. values('8','Jay2','33','3500'); 
  22. insert into `emp` (`id`, `name`, `age`, `salary`) 
  23. values('9','Tom3','23','2400'); 
  24. insert into `emp` (`id`, `name`, `age`, `salary`) 
  25. values('10','Jerry3','32','3100'); 
  26. insert into `emp` (`id`, `name`, `age`, `salary`) 
  27. values('11','Luci3','26','2900'); 
  28. insert into `emp` (`id`, `name`, `age`, `salary`) 
  29. values('12','Jay3','37','4500'); 
  30. create index idx_emp_age_salary on emp(age,salary); 

2.2 order by優化

1. filesort 排序

第一種是通過對返回數據進行排序,也就是通常說的 filesort排 序,所有不是通過索引直接返回排序結果的排序都叫 FileSort排 序。


2. using index

第二種通過有序索引順序掃描直接返回有序數據,這種情況即為 using index,不需要額外排序,操作效率高。


多字段排序

了解了MySQL的排序方式,優化目標就清晰了:盡量減少額外的排 序,通過索引直接返回有序數據。where 條件和Order by 使用 相同的索引,并且Order By 的順序和索引順序相同, 并且 Order by 的字段都是升序,或者都是降序。否則肯定需要額外的 操作,這樣就會出現FileSort。

3. 對上面兩種進行優化

通過創建合適的索引,能夠減少 Filesort 的出現,但是在某些 情況下,條件限制不能讓Filesort消失,那就需要加快Filesort 的排序操作。對于Filesort , MySQL 現在采用的是一次掃描算 法:一次性取出滿足條件的所有字段,然后在排序區 sortbuffer 中排序后直接輸出結果集。排序時內存開銷較大,但是排序效率 比兩次掃描算法要高。

MySQL 通過比較系統變量 max_length_for_sort_data 的大小 和Query語句取出的字段總大小, 來判定是否那種排序算法,如 果max_length_for_sort_data 更大,那么使用第二種優化之后 的算法;否則使用第一種。

可以適當提高 sort_buffer_size max_length_for_sort_data 系統變量,來增大排序區的大小,提高排序的效率。

2.3 group by優化

由于GROUP BY 實際上也同樣會進行排序操作,而且與ORDER BY 相比,GROUP BY 主要只是多了排序之后的分組操作。當然,如果 在分組的時候還使用了其他的一些聚合函數,那么還需要一些聚 合函數的計算。所以,在GROUP BY 的實現過程中,與 ORDER BY 一樣也可以利用到索引。

如果查詢包含 group by 但是用戶想要避免排序結果的消耗, 則 可以執行order by null 禁止排序。如下 :

  1. drop index idx_emp_age_salary on emp; 
  2. explain select age,count(*) from emp group by age; 

 

優化后

  1. explain select age,count(*) from emp group by age order by null

 

從上面的例子可以看出,第一個SQL語句需要進行"filesort",而 第二個SQL由于order by null 不需要進行 "filesort", 而上 文提過Filesort往往非常耗費時間。

創建索引

  1. create index idx_emp_age_salary on emp(age,salary); 

 

2.4 limit優化

一般分頁查詢時,通過創建覆蓋索引能夠比較好地提高性能。一 個常見又非常頭疼的問題就是 limit5000000,10 ,此時需要 MySQL排序前5000010 記錄,僅僅返回5000000 - 5000010 的記 錄,其他記錄丟棄,查詢排序的代價非常大 。

limit分頁操作, 越往后, 性能越低 :


優化方案

  1. select * from tb_sku t , (select id from tb_sku order by id limit 9000000,1) a where t.id = a.id; 

 

2.5 count優化

在很多的業務系統中,都需要考慮進行分頁操作,但是當我們執 行分頁操作時,都需要進行一次count操作,求取總記錄數,如果 數據庫表的數據量大,在InnoDB引擎中,執行count操作的性能是 比較低的,需要遍歷全表數據,對計數進行累加。

優化方案

  1. ①. 在大數據量的查詢中,只查詢數據,而不展示總記錄數 ; 
  2. ②. 通過緩存redis維護一個表的計數,來記錄數據庫表的總記錄數,在執行插入/刪除時,需要動態更新; 
  3. ③. 在數據庫表中定義一個大數據量的計數表,在執行插入/刪除時,需要動態更新。 

2.6 大批量插入優化

1. 環境準備

  1. CREATE TABLE `tb_user` ( 
  2.   `id` INT(11) NOT NULL AUTO_INCREMENT, 
  3.   `username` VARCHAR(50) NOT NULL
  4.   `passwordVARCHAR(50) NOT NULL
  5.   `nameVARCHAR(20) NOT NULL
  6.   `birthday` DATE DEFAULT NULL
  7.   `sex` CHAR(1) DEFAULT NULL
  8.   PRIMARY KEY (`id`), 
  9.   UNIQUE KEY `unique_user_username` (`username`) 
  10. ) ENGINE=INNODB DEFAULT CHARSET=utf8 ; 

當使用 load 命令導入數據的時候,適當的設置可以提高導入的效率。

對于InnoDB 類型的表,有以下幾種方式可以提高導入的效率:

主鍵順序插入

因為InnoDB類型的表是按照主鍵的順序保存的,所以將導入的數 據按照主鍵的順序排列,可以有效的提高導入數據的效率。如果 InnoDB表沒有主鍵,那么系統會自動默認創建一個內部列作為主 鍵,所以如果可以給表創建一個主鍵,將可以利用這點,來提高 導入數據的效率。

  1. 腳本文件介紹 : 
  2.   sql1.log ----> 主鍵有序 
  3.   sql2.log ----> 主鍵無序 

插入ID順序排列數據:

  1. load data local infile '/root/sql1.log' into table `tb_user` fields terminated by ',' lines terminated by '\n'

 

 插入ID無序排列數據:

關閉唯一性校驗

在導入數據前執行 SET UNIQUE_CHECKS=0,關閉唯一性校驗,在 導入結束后執行 SET UNIQUE_CHECKS=1,恢復唯一性校驗,可以 提高導入的效率。


手動提交事務

如果應用使用自動提交的方式,建議在導入前執行 SET AUTOCOMMIT=0,關閉自動提交,導入結束后再執行 SET AUTOCOMMIT=1,打開自動提交,也可以提高導入的效率。


 

責任編輯:姜華 來源: 花花與Java
相關推薦

2024-05-08 08:18:05

索引失效場景

2022-05-26 08:23:05

MySQL索引數據庫

2024-04-19 13:57:30

索引數據庫查詢

2024-01-05 14:20:55

MySQL索引優化器

2020-10-19 19:45:58

MySQL數據庫優化

2020-07-16 21:20:08

數據庫MySQL死鎖

2020-12-08 09:45:07

MySQL數據庫索引

2022-02-28 08:55:31

數據庫MySQL索引

2022-01-09 18:32:03

MySQL SQL 語句數據庫

2021-10-12 08:43:19

Cobar分庫場景

2024-12-11 08:09:54

2015-05-20 13:48:26

MySQL索引

2023-05-23 22:19:04

索引MySQL優化

2025-05-28 00:00:01

MySQL場景索引

2019-08-16 01:58:01

MySQL索引事務

2024-10-09 23:32:50

2021-05-10 11:15:28

面試索引MySQL

2019-12-18 08:00:09

MySQL數據庫ORDER BY

2022-04-26 08:51:29

MySQLgroup by

2010-10-27 13:47:50

Oracle索引
點贊
收藏

51CTO技術棧公眾號

日韩欧美黄色大片| 超碰97人人在线| 免费资源在线观看| 丁香婷婷综合五月| 日韩欧美精品一区二区| 亚洲三级视频| 国产精品一区视频网站| 99久久精品国产亚洲精品 | 成人性视频欧美一区二区三区| 日韩中文字幕不卡| 国内一区在线| 红桃视频国产一区| 国产精品直播网红| 成人中文视频| 国产精品69精品一区二区三区| 一区二区三区四区精品视频| 亚洲图片欧洲图片av| 免费高清在线观看| 欧美高清精品3d| 免费黄色在线网站| 日韩精品中文字幕在线不卡尤物| 日本中文在线| 欧美一级高清大全免费观看| aaa大片在线观看| 欧美mv日韩mv国产网站app| 新版中文在线官网| 亚洲欧美成人精品| 亚洲综合资源| 欧洲日韩成人av| 日韩系列欧美系列| 91中文字幕在线| 国产精品日韩欧美一区| 亚洲午夜精品一区二区| 国产成人在线视频免费播放| 1024精品视频| 亚洲国产一区二区三区| 成人在线免费视频| 日韩精品视频免费专区在线播放 | 精品第一国产综合精品aⅴ| 在线天堂中文资源最新版| 日韩中文字幕av| 老司机凹凸av亚洲导航| 国产精品久久久久久久久久久久 | 91香蕉视频在线下载| 99热在线精品观看| 国产在线拍揄自揄拍无码| 国产日韩欧美精品电影三级在线| 美女黄a一级视频| 色婷婷av一区二区三区大白胸| aaa日本高清在线播放免费观看| 日韩午夜激情视频| 日韩福利在线观看| 国产精品吴梦梦| 美女视频黄久久| qvod激情图片| 欧美一二三在线| 试看120秒一区二区三区| 亚洲自拍偷拍第一页| 国模无码大尺度一区二区三区| 日韩精品一区二区三区不卡| 亚洲专区一二三| 免费看电影在线| 97免费中文视频在线观看| 天天插综合网| 国产91在线亚洲| 一区二区久久久| 色呦呦在线免费观看| 午夜欧美大片免费观看| 亚洲一区二区网站| 99色在线播放| 亚洲国产精品专区久久| 久久男人av| 午夜一区二区三视频在线观看| 久久久久久久一区| 男人天堂久久久| 97在线看免费观看视频在线观看| 亚洲免费综合| 亚洲美女主播视频免费观看| 亚洲午夜av电影| 欧美激情在线| 青青青在线视频免费观看| 91精品国产91热久久久做人人| 91蜜桃臀久久一区二区| 亚洲一二三区在线| 色域天天综合网| 欧美日韩一本| 人妻少妇精品无码专区二区| 欧美精品v国产精品v日韩精品 | 污视频在线观看免费| 中文字幕亚洲色图| 模特精品在线| 天天综合入口| 欧美第一淫aaasss性| 蜜桃视频一区二区| 第一页在线观看| 国产99在线|中文| 成人在线一区二区三区| 欧美69xxxx| 91在线中文字幕| 成人免费视频在线观看| 中国色在线日|韩| 国产伦理久久久| 亚洲一区二区三区免费视频| 97久久亚洲| 男女av免费观看| 亚洲女人初尝黑人巨大| 久久精品三级| 日韩精品黄色| www.成人av.com| 欧美性猛交xxxx乱大交| 妖精视频一区二区三区| 黄色在线视频网| 久久精品福利视频| 国产成人精品影院| 国产精品一区二区av影院萌芽| 欧美日韩国产高清视频| 欧美三级欧美一级| 欧美一区二区三区久久精品| 特级全黄一级毛片| 欧美一区二区三区免费视| 欧美国产亚洲另类动漫| 精品国产亚洲一区二区在线观看| 波多野结衣av一区二区全免费观看| 精品国产乱码久久久久久1区2区 | 99久久综合国产精品| 三妻四妾完整版在线观看电视剧| 国产一区二区精品在线| 欧美亚洲综合一区| 国内精品久久久久久久影视蜜臀| 污视频网站在线看| 日韩女优在线播放| 亚洲欧美日韩成人高清在线一区| 精品视频在线你懂得| 97高清视频| 国产欧美日韩中文字幕在线| 亚洲一级片在线观看| 99久久.com| 亚洲xxxxxx| 日日噜噜噜噜夜夜爽亚洲精品| 日韩午夜激情免费电影| 美女国产一区二区| 666av成人影院在线观看| 2018国产在线| 欧美激情2020午夜免费观看| 中文字幕一区二区在线播放| 神马电影久久| 日韩a在线观看| 九色一区二区| 欧美一区二区精品在线| 国产一区二区在线观看视频| 成人深夜福利| 调教视频vk| 国产欧美在线播放| 欧美精品日韩一区| 激情偷乱视频一区二区三区| 91九色成人| 日日噜噜夜夜狠狠视频| 国产伦精品一区二区三区视频黑人 | 欧美国产日韩电影| 五月婷婷激情久久| 国产日韩专区在线| 欧美群妇大交群中文字幕| 日本麻豆一区二区三区视频| 91p九色成人| 曰韩少妇与小伙激情| 免费成人深夜夜行视频| 伊人一区二区三区久久精品| 国产精品传媒入口麻豆| 欧美福利视频| 高清电影一区| ga∨成人网| 亚洲资源视频| 2020欧美日韩在线视频| 欧美男生操女生| 91视频在线看| 911精品美国片911久久久| 久久av色综合| 精品日韩久久久| 国产精品午夜av在线| 亚洲天堂日韩电影| 亚洲一区二区三区不卡国产欧美 | av在线不卡一区| 精品中文字幕久久久久久| 中国色在线观看另类| 一区二区三区福利| 亚洲专区**| 日韩免费影院| 日韩欧美亚洲一区| 中文字幕中文字幕一区三区| 国产成+人+综合+亚洲欧洲| 亚洲国产精品成人av| 亚洲人成人一区二区在线观看 | 久久精品国产理论片免费| 毛片精品免费在线观看| 在线精品视频一区二区| 成人网在线免费视频| 欧美日韩精品| 99re91这里只有精品| 黄色在线看片| 三级av在线播放|