日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql 主表某一列 小于某一个表的两列之和_关于MySQL索引知识与小妙招

發布時間:2025/3/15 数据库 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql 主表某一列 小于某一个表的两列之和_关于MySQL索引知识与小妙招 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.1 索引的優點

  • 大大減少了服務器需要掃描的數據量,加快數據庫的檢索速度
  • 幫助服務器避免排序和臨時表
  • 將隨機io變成順序io
  • 1.2 索引的用處

  • 速查找匹配WHERE子句的行
  • 從consideration中消除行,如果可以在多個索引之間進行選擇,mysql通常會使用找到最少行的索引
  • 如果表具有多列索引,則優化器可以使用索引的任何最左前綴來查找行
  • 當有表連接的時候,從其他表檢索行數據
  • 查找特定索引列的min或max值
  • 如果排序或分組時在可用索引的最左前綴上完成的,則對表進行排序和分組
  • 在某些情況下,可以優化查詢以檢索值而無需查詢數據行
  • 1.3 索引的分類

    數據庫會默認創建索引,但是并不是給主鍵建立索引,而是給唯一鍵建立索引的,因為主鍵的特性是唯一且非空

    • 主鍵索引: 是一種特殊的唯一索引,不允許有空值。(主鍵約束,就是一個主鍵索引)
    • 唯一索引: 索引列中的值必須是唯一的,但是允許為空值。
    • 普通索引: MySQL中基本索引類型,沒有什么限制,允許在定義索引的列中插入重復值和空值,純粹為了查詢數據更快一 點。
    • 全文索引: 只有在MyISAM引擎上才能使用,只能在CHAR,VARCHAR,TEXT類型字段上使用全文索引什么是全文索引,就是在一堆文字中,通過其中的某個關鍵字等,就能找到該字段所屬的記錄行,比如有"LOL LPL 牧小農" 通過牧小農,可能就可以找到該條記錄。這里說的是可能,因為全文索引的使用涉及了很多細節,我們只需要知道這個大概意思。一般開發中,不會用到全文索引,因為其占用很大的物理空間和降低了記錄修改性,故較為少用。
    • 組合索引: 在表中的多個字段組合上創建的索引,只有在查詢條件中使用了這些字段的左邊字段時,索引才會被使用,使用組合索引時遵循最左前綴集合。例如這里由id、name和age3個字段構成的索引,索引行中就按id/name/age的順序存放,索引可以索引下面字段組合(id,name,age)、(id,name)或者(id)。如果要查詢的字段不構成索引最左面的前綴,那么就不會使用索引,比如,age或者(name,age)組合就不會使用索引查詢。

    1.4 面試技術名詞

    • 回表: 數據庫根據索引(非主鍵)找到了指定的記錄所在行后,還需要根據主鍵再次到數據塊里獲取數據,這種稱之為回表
    • 覆蓋索引: 看我寫的一篇文章:面試三輪我倒在了一道sql題上——sql性能優化
    • 最左匹配: 指在聯合索引中,如果你的 SQL 語句中用到了聯合索引中的最左邊的索引,那么這條 SQL 語句就可以利用這個聯合索引去進行匹配,如果遇到范圍查詢(>、select * from t where a=1 and b=1 and c =1; #這樣可以利用到定義的索引(a,b,c),用上a,b,c
      select * from t where a=1 and b=1; #這樣可以利用到定義的索引(a,b,c),用上a,b
      select * from t where b=1 and a=1; #這樣可以利用到定義的索引(a,b,c),用上a,c(mysql有查詢優化器)
      select * from t where a=1; #這樣也可以利用到定義的索引(a,b,c),用上a
      select * from t where b=1 and c=1; #這樣不可以利用到定義的索引(a,b,c)
      select * from t where a=1 and c=1; #這樣可以利用到定義的索引(a,b,c),但只用上a索引,b,c索引用不到
    • 索引下推: 稱為 Index Condition Pushdown (ICP),這是MySQL提供的用某一個索引對一個特定的表從表中獲取元組”,注意我們這里特意強調了“一個”,這是因為這樣的索引優化不是用于多表連接而是用于單表掃描,確切地說,是單表利用索引進行掃描以獲取數據的一種方式。

    1.5 索引采用的數據結構

    1.5.1 哈希表


    缺點︰

    1、利用hash存儲的話需要將所有的數據文件添加到內存,比較耗費內存空間
    2、如果所有的查詢都是等值查詢,那么hash確實很快,但是在企業或者實際工作環境中范圍查找的數據更多,而不是等值查詢,因此hash就不太適合了

    1.5.2 二叉樹


    缺點∶

    無論是二叉樹還是紅黑樹,都會因為樹的深度過深而造成io次數變多,影響數據讀取的效率

    1.5.3 B+樹

    B樹特點:
    1、所有鍵值分布在整棵樹中
    2、搜索有可能在非葉子結點結束,在關鍵字全集內做一次查找,性能逼近二分查找
    3、每個節點最多擁有m個子樹
    4、根節點至少有2個子樹
    5、分支節點至少擁有m/2顆子樹(除根節點和葉子節點外都是分支節點)
    6、所有葉子節點都在同一層、每個節點最多可以有m-1個key,并且以升序排列

    實例圖說明∶
    每個節點占用一個磁盤塊,一個節點上有兩個升序排序的關鍵字和三個指向子樹根節點的指針,指針存儲的是子節點所在磁盤塊的地址。兩個關鍵詞劃分成的三個范圍域對應三個指針指向的子樹的數據的范圍域。以根節點為例,關鍵字為16和34,P1指針指向的子樹的數據范圍為小于16,P2指針指向的子樹的數據范圍為16~34 ,P3指針指向的子樹的數據范圍為大于34。

    查找關鍵字過程:

  • 根據根節點找到磁盤塊1,讀入內存。【磁盤I/O操作第1次】
  • 比較關鍵字28在區間(16,34 ),找到磁盤塊1的指針P2。
  • 根據P2指針找到磁盤塊3,讀入內存。【磁盤I/O操作第2次】
  • 比較關健字28在區間(25,31 ),找到磁盤塊3的指針P2。
  • 根據P2指針找到磁盤塊8,讀入內存。【磁盤I/O 操作第3次】
  • 在磁盤塊8中的關健寧列表中找到關健字28。
  • 缺點:

    • 每個節點都有key,同時也包含data,而每個頁存儲空間是有限的,如果data比較大的話會導致每個節點存儲的k ey數量變小
    • 當存儲的數據量很大的時候會導致深度較大,增大查詢時磁盤io次數,進而影響查詢性能

    1.6 索引匹配方式

    全值匹配: 全值匹配指的是和索引中的所有列進行匹配

    explain select * from staffs where name = 'July' and age = '23' and pos = 'dev';1

    匹配最左前綴: 只匹配前面的幾列

    explain select * from staffs where name = 'July' and age = '23';explain select * from staffs where name = 'July';123

    匹配列前綴: 可以匹配某一列的值的開頭部分

    explain select * from staffs where name like 'J%';explain select * from staffs where name like '%y';123

    匹配范圍值: 可以查找某一個范圍的數據

    explain select * from staffs where name > 'Mary';1

    **精確匹配某一列并范圍匹配另外一列:**可以查詢第一列的全部和第二列的部分

    explain select * from staffs where name = 'July' and age > 25;1

    只訪問索引的查詢: 查詢的時候只需要訪問索引,不需要訪問數據行,本質上就是覆蓋索引

    explain select name,age,pos from staffs where name = 'July' and age = 25 and pos = 'dev';1

    二、哈希索引

    • 基于哈希表的實現,只有精確匹配索引所有列的查詢才有效
    • 在mysql中,只有memory的存h值,所以索引的結構十分緊湊,這讓哈希索引查找的速度非常快

    2.1 哈希索引的限制

  • 哈希索引只包含哈希值和行指針,而不存儲字段值,索引不能使用索引中的值來避免讀取行
  • 哈希索引數據并不是按照索引值順序存儲的,所以無法進行排序
  • 哈希索引不支持部分列匹配查找,哈希索引是使用索引列的全部內容來計算哈希值
  • 哈希索引支持等值比較查詢,也不支持任何范圍查詢
  • 訪問哈希索引的數據非常快,除非有很多哈希沖突,當出現哈希沖突的時候,存儲引擎必須遍歷鏈表中的所有行指針,逐行進行比較,直到找到所有符合條件的行
  • 哈希沖突比較多的話,維護的代價也會很高
  • 2.2 案例

    當需要存儲大量的URL,并且根據URL進行搜索查找,如果使用B+樹,存儲的內容就會很大:select id from url where url=""

    也可以利用將url使用CRC32做哈希,可以使用以下查詢方式:select id fom url where url="" and url_crc=CRC32("")

    此查詢性能較高原因是使用體積很小的索引來完成查找

    三、組合索引

    當包含多個列作為索引,需要注意的是正確的順序依賴于該索引的查詢,同時需要考慮如何更好的滿足排序和分組的需要

    案例: 建立組合索引 a,b,c ,不同SQL語句使用索引情況

    語句索引是否發揮作用where a=3是,只使用了awhere a=3 and b=5是,使用了a,bwhere a =3 and b = 5 and c= 4是,使用了a,b,cwhere a = 3 or c = 4否where a = 3 and c= 4是,僅使用了awhere a = 3 and b > 10 and c = 7是,使用了a,bwhere a = 3 and b like ‘%mxn%’ and c=7使用了a

    四、聚簇索引與非聚簇索引

    4.1 聚簇索引

    • 不是單獨的索引類型,而是一種數據存儲方式,指的是數據行跟相鄰的鍵值緊湊的存儲在一起,將數據存儲與索引放到了一塊,找到索引也就找到了數據
    • 如果沒有定義主鍵,InnoDB會選擇一個唯一的非空索引代替。如果沒有唯一索引,InnoDB會隱式定義一個主鍵來作為聚簇索引。InnoDB 只聚集在同一個頁面中的記錄。包含相鄰健值的頁面可能相距甚遠。

    4.2 非聚簇索引

    • 數據文件跟索引文件分開存放,將數據存儲于索引分開結構,索引結構的葉子節點指向了數據的對應行,myisam通過key_buffer把索引先緩存到內存中,當需要訪問數據時(通過索引訪問數據),在內存中直接搜索索引,然后通過索引找到磁盤相應數據,這也就是為什么索引不在key buffer命中時,速度慢的原因
    • 通過葉子節點指針找到數據頁中的數據,所以非聚簇索引是邏輯順序

    五、覆蓋索引

    5.1 基本介紹

  • 如果一個索引包含所有需要查詢的字段的值,我們稱之為覆蓋索引
  • 不是所有類型的索引都可以稱為覆蓋索引,覆蓋索引必須要存儲索引列的值
  • 不同的存儲實現覆蓋索引的方式不同,不是所有的引擎都支持覆蓋索引,memory不支持覆蓋索引
  • 5.2 優勢

    1、索引條目通常遠小于數據行大小,如果只需要讀取索引,那么mysql就會極大的較少數據訪問量
    2、因為索引是按照列值順序存儲的,所以對于IO密集型的范圍查詢會比隨機從磁盤讀取每一行數據的IO要少的多
    3、一些存儲引擎如MYISAM在內存中只緩存索引,數據則依賴于操作系統來緩存,因此要訪問數據需要一次系統調用,這可能會導致嚴重的性能問題
    4、由于INNODB的聚簇索引,覆蓋索引對INNODB表特別有用

    5.3 案例演示

    1、當發起一個被索引覆蓋的查詢時,在explain的extra列可以看到using index的信息,此時就使用了覆蓋索引
    2、在大多數存儲引擎中,覆蓋索引只能覆蓋那些只訪問索引中部分列的查詢。不過,可以進一步的進行優化,可以使用innodb的二級索引來覆蓋查詢。

    例如:actor使用innodb存儲引擎,并在last_name字段又二級索引,雖然該索引的列不包括主鍵actor_id,但也能夠用于對actor_id做覆蓋查詢

    六、優化小細節

    • 當使用索引列進行查詢的時候盡量不要使用表達式,把計算放到業務層而不是數據庫層
    • 盡量使用主鍵查詢,而不是其他索引,因為主鍵查詢不會觸發回表查詢
    • 使用前綴索引有時候需要索引很長的字符串,這會讓索引變的大且慢,通常情況下可以使用某個列開始的部分字符串,這樣大大的節約索引空間,從而提高索引效率,但這會降低索引的選擇性,索引的選擇性是指不重復的索引值和數據表記錄總數的比值,范圍從1/#T到1之間。索引的選擇性越高則查詢效率越高,因為選擇性更高的索引可以讓mysql在查找的時候過濾掉更多的行。
      一般情況下某個列前綴的選擇性也是足夠高的,足以滿足查詢的性能,但是對應BLOB,TEXT,VARCHAR類型的列,必須要使用前綴索引,因為mysql不允許索引這些列的完整長度,使用該方法的訣竅在于要選擇足夠長的前綴以保證較高的選擇性,通過又不能太長。
    --創建數據表create table citydemo(city varchar(50) not null);insert into citydemo(city) select city from city;--重復執行5次下面的sql語句insert into citydemo(city) select city from citydemo;--更新城市表的名稱update citydemo set city=(select city from city order by rand() limit 1);--查找最常見的城市列表,發現每個值都出現45-65次,select count(*) as cnt,city from citydemo group by city order by cnt desc limit 10;--查找最頻繁出現的城市前綴,先從3個前綴字母開始,發現比原來出現的次數更多,可以分別截取多個字符查看城市出現的次數select count(*) as cnt,left(city,3) as pref from citydemo group by pref order by cnt desc limit 10;select count(*) as cnt,left(city,7) as pref from citydemo group by pref order by cnt desc limit 10;--此時前綴的選擇性接近于完整列的選擇性--還可以通過另外一種方式來計算完整列的選擇性,可以看到當前綴長度到達7之后,再增加前綴長度,選擇性提升的幅度已經很小了select count(distinct left(city,3))/count(*) as sel3,count(distinct left(city,4))/count(*) as sel4,count(distinct left(city,5))/count(*) as sel5,count(distinct left(city,6))/count(*) as sel6,count(distinct left(city,7))/count(*) as sel7,count(distinct left(city,8))/count(*) as sel8 from citydemo;--計算完成之后可以創建前綴索引alter table citydemo add key(city(7));--注意:前綴索引是一種能使索引更小更快的有效方法,但是也包含缺點:mysql無法使用前綴索引做order by 和 group by。 12345678910111213141516171819202122232425262728293031
    • 使用索引掃描來排序mysql有兩種方式可以生成有序的結果:通過排序操作或者按索引順序掃描,如果explain出來的type列的值為index,則說明mysql使用了索引掃描來做排序
      掃描索引本身是很快的,因為只需要從一條索引記錄移動到緊接著的下一條記錄。但如果索引不能覆蓋查詢所需的全部列,那么就不得不每掃描一條索引記錄就得回表查詢一次對應的行,這基本都是隨機IO,因此按索引順序讀取數據的速度通常要比順序地全表掃描慢
      ? mysql可以使用同一個索引即滿足排序,又用于查找行,如果可能的話,設計索引時應該盡可能地同時滿足這兩種任務。
      ? 只有當索引的列順序和order by子句的順序完全一致,并且所有列的排序方式都一樣時,mysql才能夠使用索引來對結果進行排序,如果查詢需要關聯多張表,則只有當orderby子句引用的字段全部為第一張表時,才能使用索引做排序。order by子句和查找型查詢的限制是一樣的,需要滿足索引的最左前綴的要求,否則,mysql都需要執行順序操作,而無法利用索引排序
    • union all,in,or都能夠使用索引,但是推薦使用in
    • 范圍列可以用到索引,范圍條件是:,范圍列可以用到索引,但是范圍列后面的列無法用到索引,索引最多用于一個范圍列
    • 強制類型轉換會全表掃描
    create table user(id int,name varchar(10),phone varchar(11));alter table user add index idx_1(phone);explain select * from user where phone=13800001234;(不會觸發索引)explain select * from user where phone='13800001234';(觸發索引)1234
    • 更新十分頻繁,數據區分度不高的字段上不宜建立索引更新會變更B+樹,更新頻繁的字段建議索引會大大降低數據庫性能.
      類似于性別這類區分不大的屬性,建立索引是沒有意義的,不能有效的過濾數據,
      一般區分度在80%以上的時候就可以建立索引,區分度可以使用 count(distinct(列名))/count(*) 來計算

    總結

    以上是生活随笔為你收集整理的mysql 主表某一列 小于某一个表的两列之和_关于MySQL索引知识与小妙招的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 欧美性吧| 亚洲色图丝袜 | 国产成人综合av | 99久久久无码国产精品性黑人 | 黄色一级片 | 中文字幕在线乱 | 日韩在线观看第一页 | 成年人在线观看 | 热热色国产 | 在线观看欧美精品 | 美女脱光衣服让男人捅 | 欧美亚洲中文精品字幕 | 欧美视频一区二区三区四区在线观看 | 天堂成人在线视频 | 久久久久国产精品一区二区 | 日韩精品伦理 | 国产亚洲色婷婷久久99精品 | 男生和女生一起差差差视频 | 精品国产乱码久久久久久图片 | 在线观看黄色片网站 | 丁香婷婷一区二区三区 | 中国少妇做爰全过程毛片 | 亚洲欧洲日韩在线 | 成人爱爱| 亚洲经典在线观看 | 精品人妻伦一二三区久 | 老牛影视av牛牛影视av | 好色综合 | 中文字幕亚洲国产 | 交专区videossex非洲 | 欧美一区日韩一区 | 日本特级黄色录像 | 日韩国产成人在线 | 亚洲无吗一区二区三区 | 毛片av在线 | 婷婷射| 伊人免费在线 | 欧美一区二区免费视频 | 在线观看免费国产视频 | 自拍偷拍欧美日韩 | julia一区二区三区在线观看 | 午夜婷婷色 | 国产精品不卡一区二区三区 | 精品久久一 | 中文字幕免费一区 | 亚洲激情影院 | 在线观看精品国产 | 天堂国产一区二区三区 | 成人人人人人欧美片做爰 | 五月天丁香在线 | 日韩中文字幕在线观看视频 | 亚洲国产一区二区三区 | 亚洲欧美激情另类校园 | 天天干天天爱天天射 | 激情福利在线 | 北条麻妃av在线播放 | 亚洲一区二区黄片 | 法国经典free性复古xxxx | 亚洲av毛片成人精品 | 精品无人区无码乱码毛片国产 | 亚洲午夜一区二区三区 | 波多野吉衣久久 | 黄色一级网站 | 丝袜老师扒开让我了一夜漫画 | 五月婷婷一区二区三区 | 欧美国产一级 | 五月婷婷一区二区 | 一品道av | 综合在线视频 | 91精品国产综合久久国产大片 | 亚洲欧美综合视频 | 嫩草影院懂你的影院 | 男女一级片 | 在线观看av网页 | 欧美日本高清视频 | 亚洲天堂成人在线 | 国产免费一区二区三区四区五区 | 久久精品欧美视频 | 性色在线观看 | 欧美一区二区在线视频 | 黄色片视频免费在线观看 | 伊人久久一区二区三区 | 日日夜夜网站 | 精品久久免费 | 日本五十路 | av调教| 国产最新视频在线 | 成人av无码一区二区三区 | 天天射天天爽 | 国产一区二区h | h视频在线看 | 精品99在线观看 | 亚洲AV成人无码久久精品同性 | 后进极品美女圆润翘臀 | 毛毛毛片 | av片免费在线播放 | 3d动漫啪啪精品一区二区中文字幕 | 亚洲先锋影音 | 天天操夜夜撸 |