亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 數據庫 > MySQL > 正文

在MySQL中實現二分查找的詳細教程

2024-07-24 13:07:27
字體:
來源:轉載
供稿:網友

這篇文章主要介紹了在MySQL中實現二分查找的詳細教程,來自計算機研究生考試原題,需要的朋友可以參考下

給定一個升序排列的自然數數組,數組中包含重復數字,例如:[1,2,2,3,4,4,4,5,6,7,7]。問題:給定任意自然數,對數組進行二分查找,返回數組正確的位置,給出函數實現。注:連續相同的數字,返回第一個匹配位置還是最后一個匹配位置,由函數傳入參數決定。

我為什么會出這道題目?

二分查找在數據庫內核實現中非常重要

在數據庫的內核實現中,二分查找是一個非常重要的邏輯,幾乎99%以上的SQL語句(所有索引上的范圍掃描/等值查詢/Unique查詢等),都會使用到二分查找進行數據的定位。

考慮一個數據庫表t1(a int primary key, b int),表上的b字段有一個B+樹索引,表中記錄的b字段取值,就是題目中的[1,2,2,3,4,4,4,5,6,7,7]序列。此時,給定以下的兩條查詢語句,就是使用到了不同的二分查找邏輯:

SQL1:

 

 
  1. select * from t1 where b > 4; 

SQL2:

 

 
  1. select * from t1 where b >= 4; 

針對SQL1,索引的二分查找,就需要跳過所有的4,從最后一個4之后開始返回所有記錄;針對SQL2,二分查找就需要定位到第一個4,然后順序讀取所有記錄。

除此之外,針對數據庫中其他的查詢邏輯,二分查找還需要附帶更多的功能,例如:

SQL3:

 

 
  1. select * from t1 where b < 2; 

SQL4:

 

 
  1. select * from t1 where b <= 2; 

由于數據庫索引同時支持反向掃描,因此SQL3、SQL4的語句,都可以使用索引反向掃描。反向掃描時,SQL3需要定位到索引中的第一個2;而SQL4,則需要定位到索引的最后一個2,然后開始反向返回滿足查詢條件的索引記錄。

二分查找在程序設計中,是一個十分基礎并且易錯的功能

第一個真正正確的二分查找算法,在第一個二分查找實現之后的12年,才被發表出來。通過Google,輸入Binary Search或者是二分查找關鍵字,有大量的相關的文章或者博客討論此話題。

二分查找實現,需要注意的問題

本文不準備詳細介紹一個正確的二分查找應該是如何實現的,畢竟現在網上有著大量的正確版本。接下來,根據批改試卷過程中發現的一些問題,做一些簡單的分析,希望對大家實現一個有效的二分查找算法,甚至是一個數據庫內可用的二分查找算法,有所幫助。

問題一:是否檢查參數的有效性

大量的試卷,在給出此問題的解決算法時,直接拿著low,high參數開始進行計算,但是卻沒有檢查low/high參數。low/high是否相同,數組中是否存在記錄?low/high構成的區間是否有效?代碼的魯棒性不足。

在數據庫的二分查找實現中,一般是對一個索引頁面進行二分查找。索引頁面中有可能根本不存在用戶的記錄(索引頁面中的記錄全部被刪除,又沒有與兄弟頁面合并時),此時,low/high均為0,此時如果根據low/high計算出來的mid進行記錄的讀取,就存在邏輯錯誤。

問題二:二分查找中值的計算

這是一個經典的話題,如何計算二分查找中的中值?試卷中,大家一般給出了兩種計算方法:

算法一: mid = (low + high) / 2

算法二: mid = low + (high – low)/2

乍看起來,算法一簡潔,算法二提取之后,跟算法一沒有什么區別。但是實際上,區別是存在的。算法一的做法,在極端情況下,(low + high)存在著溢出的風險,進而得到錯誤的mid結果,導致程序錯誤。而算法二能夠保證計算出來的mid,一定大于low,小于high,不存在溢出的問題。

回到數據庫二分查找,數據庫的一個索引頁面(大小一般是8k或者是16k),能夠存儲的索引記錄是有限的,因此肯定不會出現(low + high)溢出的風險。這也是為什么InnoDB中的中值,采用的就是算法一的實現。但是,作為一個嚴謹的程序設計人員,還是推薦使用算法二,將任何潛在的風險,扼殺于搖籃之中。

問題三:遞歸實現二分查找

超過一半的試卷,使用了遞歸調用的方式實現二分查找。不能說遞歸實現有錯,而是在于實現效率問題。總所周知,遞歸調用存在著壓棧/出棧的開銷,其效率是比較低下的。而以數據庫這樣一個極端優化代碼效率,提供快速查詢響應的系統來說,效率是第一位的。不建議使用遞歸方式實現二分查找,至少在數據庫內核實現中是不允許使用的。據我所知,所有的開源數據庫系統,例如:InnoDB,PostgreSQL都未采用遞歸方式實現二分查找。

問題四:如何查找第一個/最后一個等值

回到題目,要求根據傳入的參數不同,返回第一個/最后一個等值項。在本文的背景部分,我也解釋了此問題對應的數據庫查詢(>,>=查詢需求是不同的)。在試卷中,超過80%的同學的答案都是先進行二分查找,待定位到相同值之后,再根據傳入的flag(用戶需求:flag = 1,返回第一個等值項;flag = 0,返回最后一個等值項),進行順序遍歷,直至定位到滿足條件的項。

同樣,不能說這個實現是錯的,但是也存在著性能問題。性能性能性能,永遠是數據庫內核實現考慮的重點之一(相信也是所有應用程序的一個指標)。數據庫中,除了主鍵索引/Unique索引能夠保證鍵值唯一之外,很多二級輔助索引都是存在相同鍵值的,有時相同鍵值的項會超過千項(考慮一個用戶的訂單,或者是購買記錄)。

假設一個索引頁面,保存著400項記錄,均為相同鍵值。此時,使用先二分查找,后順序遍歷的算法,二分查找只能使用一次,順序遍歷199次,最終對比了200次。效率非常之低。當然,我也欣喜的看到另外一小部分同學的做法(我期待看到的算法),用flag來糾正每次比較的最終結果。例如:比較相等(相等用0表示,大于為1,小于為-1),但是flag = 1,則返回糾正后的比較結果為1,需要移動二分查找的high到mid,繼續二分(反之,若flag = 0,則返回糾正后的結果為-1,需要移動二分查找的low到mid,繼續二分)。如此一來,等值仍舊可以進行二分查找,最終的對比只需要9次,遠遠小于200次。

此問題,進一步引出了下一個問題,數據庫中如何實現一個通用的,更為復雜的二分查找算法?

問題五:數據庫中的二分查找實現舉例

數據庫中的二分查找,更為復雜,需要實現一個通用型的二分查找算法,使用于各種不同的SQL查詢場景。

InnoDB針對不同的SQL語句,總結出四種不同的Search Mode,分別為:

#define PAGE_CUR_G 1 >查詢

#define PAGE_CUR_GE 2 >=,=查詢

#define PAGE_CUR_L 3 <查詢

#define PAGE_CUR_LE 4 <=查詢

然后根據這四種不同的Search Mode,在二分查找碰到相同鍵值時進行調整。例如:若Search Mode為PAGE_CUR_G或者是PAGE_CUR_LE,則移動low至mid,繼續進行二分查找;若Search Mode為PAGE_CUR_GE或者是PAGE_CUR_L,則移動high至mid,繼續進行二分查找。

我們的TNT引擎,采用了與InnoDB不同的方案,但是也實現了相同的功能。TNT引擎針對相同鍵值的調整總結為下圖,在此我就不做解釋了,大家可以嘗試著自己進行分析。

/* 操作符 includeKey forward compare result: 1 0 -1 */

=============================================================================

>= 1 1 | 1 -1 -1

= 1 1 | 1 -1 -1

> 0 1 | 1 1 -1

< 0 0 | 1 -1 -1

<= 1 0 | 1 1 -1

=============================================================================

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产亚洲视频在线观看| 97在线看免费观看视频在线观看| 2018国产精品视频| 久久免费成人精品视频| 成人网在线视频| 亚洲自拍偷拍视频| 26uuu另类亚洲欧美日本一| 日韩日本欧美亚洲| 欧美疯狂性受xxxxx另类| 国产精品久久久久久久久久免费| 欧美专区福利在线| 日韩av在线免费| 91香蕉嫩草神马影院在线观看| 欧美性猛交xxxx乱大交3| 亚洲一级黄色片| 欧美日韩国产成人在线观看| 91亚洲精品一区二区| 亚洲电影免费观看高清| 欧美日韩国产成人在线| 亚洲免费精彩视频| 亚洲欧美制服中文字幕| 欧美视频在线观看免费| 国产一区二区三区视频| 欧美国产日韩一区二区三区| 中文字幕在线视频日韩| 国产亚洲美女精品久久久| 亚洲精品美女久久久久| 91久久久久久| 中文字幕视频一区二区在线有码| 国产69精品久久久久9| 国产精品入口免费视频一| 亚洲天堂网在线观看| 中文字幕精品久久| 性欧美在线看片a免费观看| 91精品国产综合久久男男| 国产一区二区黑人欧美xxxx| 久久久久中文字幕2018| 自拍偷拍亚洲在线| 国产亚洲欧美日韩一区二区| 欧美精品在线第一页| 日韩黄色av网站| 欧美激情第6页| 91精品久久久久久久久久久久久久| 久久99久久99精品免观看粉嫩| 亚洲精品成人久久| 精品国偷自产在线视频| 亚洲视频第一页| 人人澡人人澡人人看欧美| 日本不卡免费高清视频| 亚洲第一福利网| 久久免费精品日本久久中文字幕| 亚洲国产精品专区久久| 欧美老女人在线视频| 中文字幕精品在线视频| 欧美xxxwww| 日产精品久久久一区二区福利| 久久成人人人人精品欧| 亚洲国产精品一区二区久| 亚洲精品成a人在线观看| 国产视频福利一区| 国产日韩欧美一二三区| 伊人男人综合视频网| 日韩av色在线| 欧美亚洲成人免费| 日韩av中文字幕在线免费观看| 中文字幕日韩欧美精品在线观看| 国产婷婷97碰碰久久人人蜜臀| 91国产高清在线| 美女视频黄免费的亚洲男人天堂| 在线看国产精品| 国产视频亚洲视频| 精品国内亚洲在观看18黄| 亚洲free性xxxx护士白浆| 亚洲理论片在线观看| 国产噜噜噜噜久久久久久久久| 久久综合久久88| 欧美性xxxx极品hd满灌| 久久久黄色av| 亚洲第一在线视频| 国产精品99久久久久久白浆小说| 欧美一级大片在线观看| 欧美日韩亚洲天堂| 欧美高清无遮挡| 久久久久久久久久久久久久久久久久av| 国产精品麻豆va在线播放| 97超级碰碰碰久久久| 中文字幕一区二区精品| 亚洲欧美日韩国产中文| 深夜福利亚洲导航| 日韩av影片在线观看| 日本精品视频网站| 欧美性理论片在线观看片免费| 日韩动漫免费观看电视剧高清| 成人激情视频在线观看| 久久99视频免费| 亚洲视频在线免费看| 亚洲男人天堂九九视频| 欧美黑人巨大xxx极品| 亚洲美女视频网| 欧美性xxxx极品高清hd直播| 欧美极品xxxx| 国产日韩在线精品av| 欧美一区二区三区免费观看| 成人日韩在线电影| 波霸ol色综合久久| 亚洲精品久久在线| 久久777国产线看观看精品| 欧美成人合集magnet| 国产精品久久久久久久久久| 欧美激情一区二区三区久久久| 亚洲黄色在线看| 黑人巨大精品欧美一区二区三区| 国产精品一区二区三区久久久| 国产成人久久久精品一区| 欧美日韩中文字幕在线| 亚洲欧美另类中文字幕| 日韩av网站导航| 久久亚洲精品视频| 欧美精品久久久久久久久久| 久久艹在线视频| 亚洲女人被黑人巨大进入al| 日韩电影中文字幕一区| 亚洲a在线观看| 国产视频精品免费播放| 日韩av在线免费观看一区| 亚洲精品视频播放| 欧美亚洲激情在线| 日韩高清有码在线| 亚洲欧洲xxxx| 国产欧美欧洲在线观看| 国产精品精品视频一区二区三区| 精品久久久91| 国产视频精品xxxx| 色悠久久久久综合先锋影音下载| 久热精品视频在线免费观看| 久久成人18免费网站| 国内精品在线一区| 欧美片一区二区三区| 日韩高清免费观看| 国产精品女视频| 久久不射热爱视频精品| 欧美视频精品一区| 夜夜嗨av一区二区三区四区| 国产精品中文久久久久久久| 777午夜精品福利在线观看| 91亚洲午夜在线| 亚洲图片制服诱惑| 在线播放国产一区二区三区| 日韩美女主播视频| 久久香蕉国产线看观看av| 国产精品免费视频xxxx| 亚洲欧美国产精品久久久久久久| 丝袜亚洲另类欧美重口| 91国产在线精品| 久久精品99久久久香蕉| 国产极品精品在线观看| 日韩欧美成人免费视频| 国产日韩在线观看av| 国产精品丝袜久久久久久高清| 亚洲天堂av高清| 日韩亚洲国产中文字幕| 国产精品久久久久久久久影视| 国产精品入口福利| 日韩欧美一区二区三区久久|