1、創(chuàng)建測(cè)試表,

勃利網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)公司!從網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、成都響應(yīng)式網(wǎng)站建設(shè)公司等網(wǎng)站項(xiàng)目制作,到程序開發(fā),運(yùn)營(yíng)維護(hù)。創(chuàng)新互聯(lián)公司2013年開創(chuàng)至今到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來(lái)保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)公司。
create table test_order(id number, value1 number, value2 number);
2、插入測(cè)試數(shù)據(jù)
insert into test_order values(1,1001,2001);
insert into test_order values(2,1002,2002);
insert into test_order values(3,1003,2003);
insert into test_order values(4,1004,2004);
insert into test_order values(5,1005,2005);
3、查詢表中所有記錄數(shù),select t.*, rowid from test_order t,
4、編寫sql,按value1字段做升序,按value2字段做降序,
select t.*,
? ? ? ?row_number() over(order by value1) rn1,
? ? ?row_number() over(order by value2 desc) rn12
from test_order t
在 Web 應(yīng)用程序中跨大型數(shù)據(jù)集分頁(yè)記錄似乎是一個(gè)簡(jiǎn)單的問題,但實(shí)際上很難擴(kuò)展。兩種主要的分頁(yè)策略是偏移/限制和游標(biāo)。
我們將首先看一下這兩種方法,然后稍作修改,可以使偏移/限制非常高效。
偏移/限制分頁(yè)
偏移/限制方法是迄今為止最常見的方法,它通過(guò)跳過(guò)一定數(shù)量的記錄(頁(yè))并將結(jié)果限制為一頁(yè)來(lái)工作。
例如,假設(shè)您的應(yīng)用程序配置為每頁(yè)顯示 15 條記錄。您的 SQL 將如下所示:
這是最常見的,因?yàn)樗浅:?jiǎn)單,易于推理,并且?guī)缀趺總€(gè)框架都支持它。
除了易于實(shí)現(xiàn)之外,它還具有頁(yè)面可直接尋址的優(yōu)點(diǎn)。例如,如果您想直接導(dǎo)航到第 20 頁(yè),您可以這樣做,因?yàn)樵撈屏亢苋菀子?jì)算。
但是有一個(gè)主要的缺點(diǎn),它潛伏在數(shù)據(jù)庫(kù)處理偏移量的方式中。偏移量告訴數(shù)據(jù)庫(kù)放棄從查詢中返回的前N個(gè)結(jié)果。不過(guò)數(shù)據(jù)庫(kù)仍然要從磁盤上獲取這些行。
如果你丟棄的是100條記錄,這并不重要,但如果你丟棄的是100,000條記錄,數(shù)據(jù)庫(kù)就會(huì)為了丟棄這些結(jié)果而做大量的工作。
在實(shí)踐中,這意味著第一個(gè)頁(yè)面會(huì)快速加載,之后的每一個(gè)頁(yè)面都會(huì)變得越來(lái)越慢,直到你達(dá)到一個(gè)點(diǎn),網(wǎng)絡(luò)請(qǐng)求可能會(huì)直接超時(shí)。
基于游標(biāo)的分頁(yè)
基于游標(biāo)的分頁(yè)彌補(bǔ)了偏移/限制的一些不足,同時(shí)引入了一些自己的不足。
基于游標(biāo)的分頁(yè)是通過(guò)存儲(chǔ)一些關(guān)于最后呈現(xiàn)給用戶的記錄的狀態(tài),然后根據(jù)這個(gè)狀態(tài)來(lái)進(jìn)行下一次查詢。
因此,它不是按順序獲取所有的記錄并丟棄前N條,而是只獲取最后一個(gè)位置N之后的記錄。
如果按ID排序,SQL可能看起來(lái)像這樣。
你可能已經(jīng)看到了其中的好處。因?yàn)槲覀冎郎洗蜗蛴脩粽故镜腎D,我們知道下一個(gè)頁(yè)面將以一個(gè)更高的ID開始。我們甚至不需要檢查ID較低的行,因?yàn)槲覀儼俜种倏隙ǖ刂滥切┬胁恍枰伙@示。
在上面的例子中,我特別說(shuō)明了ID可能不是連續(xù)的,也就是說(shuō),可能有缺失的記錄。這使得我們無(wú)法計(jì)算出哪些記錄會(huì)出現(xiàn)在某一頁(yè)面上,你必須跟蹤之前那一頁(yè)面上的最后一條記錄是什么。
與偏移/限制分頁(yè)不同,使用游標(biāo)分頁(yè)時(shí),頁(yè)面不能直接尋址,你只能導(dǎo)航到 "下一頁(yè) "或 "上一頁(yè)"。
不過(guò)光標(biāo)分頁(yè)的好處是在任何數(shù)量的頁(yè)面上都很迅速。它也很適合無(wú)限滾動(dòng),在這種情況下,頁(yè)面首先不需要可以直接尋址。
Laravel文檔中有一些關(guān)于偏移量和游標(biāo)之間的權(quán)衡的好的背景。
cursor -vs-offset-pagination
考慮到所有這些,讓我們來(lái)看看一個(gè)偏移/限制優(yōu)化,可以使它的性能足以在成千上萬(wàn)的頁(yè)面上使用。
使用遞延join的Offset/Limit
遞延連接(deferred join )是一種技術(shù),它將對(duì)要求的列的訪問推遲到應(yīng)用了偏移量和限制之后。
使用這種技術(shù),我們創(chuàng)建一個(gè)內(nèi)部查詢,可以用特定的索引進(jìn)行優(yōu)化,以獲得最大的速度,然后將結(jié)果連接到同一個(gè)表,以獲取完整的行。
它看起來(lái)像這樣:
這種方法的好處可以根據(jù)你的數(shù)據(jù)集有很大的不同,但是這種方法允許數(shù)據(jù)庫(kù)盡可能少地檢查數(shù)據(jù),以滿足用戶的意圖。
查詢中 "昂貴的 "select *部分只在與內(nèi)部查詢相匹配的15條記錄上運(yùn)行。所有數(shù)據(jù)的Select都被推遲了,因此被稱為推遲join。
這種方法不太可能比傳統(tǒng)的偏移/限制性能差,盡管它是可能的,所以一定要在你的數(shù)據(jù)上進(jìn)行測(cè)試!
Laravel實(shí)現(xiàn)
我們?nèi)绾伟堰@一點(diǎn)帶到我們最喜歡的網(wǎng)絡(luò)框架,如Laravel和Rails?
讓我們具體看看Laravel,因?yàn)槲也恢繰ails。
感謝Laravel的macroable特性,我們可以擴(kuò)展Eloquent Query Builder來(lái)添加一個(gè)新的方法,叫做deferredPaginate。為了保持一致性,我們將模仿常規(guī)分頁(yè)的簽名。
我們將嘗試做盡可能少的自定義工作,并將大部分工作留給 Laravel。
這是我們要做的:
這應(yīng)該為我們提供 LaravelLengthAwarePaginator 和延遲連接的所有好處!
一個(gè)Github倉(cāng)庫(kù)
遞延Join和覆蓋索引
還沒有完成...
使用遞延Join的主要好處是減少了數(shù)據(jù)庫(kù)必須檢索然后丟棄的數(shù)據(jù)量。我們可以通過(guò)幫助數(shù)據(jù)庫(kù)獲得它需要的數(shù)據(jù)而更進(jìn)一步,而無(wú)需獲取底層行。
這樣做的方法稱為“覆蓋索引covering index”,它是確保快速偏移/限制分頁(yè)的最終解決方案。
覆蓋索引是一個(gè)索引,在這個(gè)索引中,查詢的所有需要的字段都包含在索引本身中。當(dāng)一個(gè)查詢的所有部分都能被一個(gè)索引 "覆蓋 "時(shí),數(shù)據(jù)庫(kù)根本不需要讀取該行,它可以從索引中獲得它需要的一切。
請(qǐng)注意,覆蓋索引并不是以任何特殊方式創(chuàng)建的。它只是指一個(gè)索引滿足了一個(gè)查詢所需要的一切的情況。一個(gè)查詢上的覆蓋索引很可能不是另一個(gè)查詢上的覆蓋索引。
在接下來(lái)的幾個(gè)例子中,我們將使用這個(gè)基本的表,我把它填滿了~1000萬(wàn)條記錄。
讓我們看一個(gè)僅select索引列的簡(jiǎn)單查詢。在這種情況下,我們將從email表中進(jìn)行select contacts。
在這種情況下,數(shù)據(jù)庫(kù)根本不需要讀取基礎(chǔ)行。在MySQL中,我們可以通過(guò)運(yùn)行一個(gè)解釋并查看額外的列來(lái)驗(yàn)證這一點(diǎn):
extra: using index告訴我們,MySQL能夠只使用索引來(lái)滿足整個(gè)查詢,而不看基礎(chǔ)行。
如果嘗試select name from contacts limit 10, 我們將期望MySQL必須到該行去獲取數(shù)據(jù),因?yàn)槊謓ame沒有被索引。這正是發(fā)生的情況,由下面的解釋顯示。
extra不再顯示 using index,所以我們沒有使用覆蓋索引。
假設(shè)你每頁(yè)有15條記錄,你的用戶想查看第1001頁(yè),你的內(nèi)部查詢最終會(huì)是這樣的。
select id from contacts order by id limit 15 OFFSET 150000
explain結(jié)果顯示:
MySQL能夠單看索引來(lái)執(zhí)行這個(gè)查詢。它不會(huì)簡(jiǎn)單地跳過(guò)前15萬(wàn)行,在使用offset是沒有辦法的,但它不需要讀取15萬(wàn)行。(只有游標(biāo)分頁(yè)可以讓你跳過(guò)所有的行)。
即使使用覆蓋索引和延遲連接,當(dāng)你到達(dá)后面的頁(yè)面時(shí),結(jié)果也會(huì)變慢,盡管與傳統(tǒng)的偏移/限制相比,它應(yīng)該是最小的。使用這些方法,你可以輕易地深入到數(shù)千頁(yè)。
更好的覆蓋索引
這里的很多好處取決于擁有良好的覆蓋索引,所以讓我們稍微討論一下。一切都取決于您的數(shù)據(jù)和用戶的使用模式,但是您可以采取一些措施來(lái)確保查詢的最高命中率。
這將主要與 MySQL 對(duì)話,因?yàn)槟鞘俏矣薪?jīng)驗(yàn)的地方。其他數(shù)據(jù)庫(kù)中的情況可能會(huì)有所不同。
大多數(shù)開發(fā)人員習(xí)慣于為單列添加索引,但沒有什么能阻止您向多列添加索引。事實(shí)上,如果您的目標(biāo)是為昂貴的分頁(yè)查詢創(chuàng)建覆蓋索引,您幾乎肯定需要一個(gè)多列索引。
當(dāng)你試圖為分頁(yè)優(yōu)化一個(gè)索引時(shí),一定要把按列排序放在最后。如果你的用戶要按update_at排序,這應(yīng)該是你復(fù)合索引中的最后一列。
看看下面這個(gè)包括三列的索引。
在MySQL中,復(fù)合索引是從左到右訪問的,如果一個(gè)列缺失,或者在第一個(gè)范圍條件之后,MySQL會(huì)停止使用一個(gè)索引。
MySQL 將能夠在以下場(chǎng)景中使用該索引:
如果你跳過(guò)is_archived,MySQL將無(wú)法訪問update_at,將不得不訴諸于沒有該索引的排序,或者根本不使用該索引,所以要確保你有相應(yīng)的計(jì)劃。
主鍵始終存在
在MySQL的InnoDB中,所有的索引都附加了主鍵。這意味著(email)的索引實(shí)際上是(email,id)的索引,當(dāng)涉及到覆蓋索引和延遲連接時(shí),這是相當(dāng)重要的。
查詢select email from contacts order by id完全被email上的一個(gè)索引所覆蓋,因?yàn)镮nnoDB將id附加到了該索引上。
使用我們上面的綜合例子,你可以看到這有什么好處。
因?yàn)閺?fù)合索引涵蓋了is_deleted, is_archived, updated_at, 和(通過(guò)InnoDB的功能)id,整個(gè)查詢可以僅由索引來(lái)滿足。
降序索引
大多數(shù)時(shí)候,用戶都在尋找 "最新的 "項(xiàng)目,即最近更新或創(chuàng)建的項(xiàng)目,這可以通過(guò)按update_at DESC排序來(lái)滿足。
如果你知道你的用戶主要是以降序的方式對(duì)他們的結(jié)果進(jìn)行排序,那么特別將你的索引設(shè)為降序索引可能是有意義的。
MySQL 8是第一個(gè)支持降序索引的MySQL版本。
如果你在explain的Extra部分看到向后索引掃描,你也許可以配置一個(gè)更好的索引。
前向索引掃描比后向掃描快~15%,所以你要按照你認(rèn)為你的用戶最常使用的順序添加索引,并為少數(shù)使用情況承擔(dān)懲罰。
太陽(yáng)底下無(wú)新事
這種使用偏移/限制分頁(yè)與延遲連接和覆蓋索引的方法并不是銀彈。
僅僅是遞遲連接就可以讓你的速度得到很好的提升,但是需要花一些額外的心思來(lái)設(shè)計(jì)正確的索引以獲得最大的好處。
有一種觀點(diǎn)認(rèn)為,遞延連接應(yīng)該是框架中默認(rèn)的偏移offset/限制limit方法,而任何時(shí)候覆蓋索引的出現(xiàn)都只是一種獎(jiǎng)勵(lì)。我還沒有在足夠多的生產(chǎn)環(huán)境中測(cè)試過(guò),所以還沒有強(qiáng)烈主張這樣做。
使用MySQL的遞延Join連接實(shí)現(xiàn)高效分頁(yè) - Aaron
MySQL排序 有時(shí)候很容易記混,我這里把他記錄了下:
desc是降序
asc是升序(默認(rèn)不寫就是升序)
MySql語(yǔ)句:
1.帶條件的排序
2.不帶條件的sql直接排序
MySQL索引通常是被用于提高WHERE條件的數(shù)據(jù)行匹配或者執(zhí)行聯(lián)結(jié)操作時(shí)匹配其它表的數(shù)據(jù)行的搜索速度。
MySQL也能利用索引來(lái)快速地執(zhí)行ORDER BY和GROUP BY語(yǔ)句的排序和分組操作。
通過(guò)索引優(yōu)化來(lái)實(shí)現(xiàn)MySQL的ORDER BY語(yǔ)句優(yōu)化:
1、ORDER BY的索引優(yōu)化。如果一個(gè)SQL語(yǔ)句形如:
SELECT [column1],[column2],…. FROM [TABLE] ORDER BY [sort];
在[sort]這個(gè)欄位上建立索引就可以實(shí)現(xiàn)利用索引進(jìn)行order by 優(yōu)化。
2、WHERE + ORDER BY的索引優(yōu)化,形如:
SELECT [column1],[column2],…. FROM [TABLE] WHERE [columnX] = [value] ORDER BY [sort];
建立一個(gè)聯(lián)合索引(columnX,sort)來(lái)實(shí)現(xiàn)order by 優(yōu)化。
注意:如果columnX對(duì)應(yīng)多個(gè)值,如下面語(yǔ)句就無(wú)法利用索引來(lái)實(shí)現(xiàn)order by的優(yōu)化
SELECT [column1],[column2],…. FROM [TABLE] WHERE [columnX] IN ([value1],[value2],…) ORDER BY[sort];
3、WHERE+ 多個(gè)字段ORDER BY
SELECT * FROM [table] WHERE uid=1 ORDER x,y LIMIT 0,10;
建立索引(uid,x,y)實(shí)現(xiàn)order by的優(yōu)化,比建立(x,y,uid)索引效果要好得多。
MySQL Order By不能使用索引來(lái)優(yōu)化排序的情況
* 對(duì)不同的索引鍵做 ORDER BY :(key1,key2分別建立索引)
SELECT * FROM t1 ORDER BY key1, key2;
* 在非連續(xù)的索引鍵部分上做 ORDER BY:(key_part1,key_part2建立聯(lián)合索引;key2建立索引)
SELECT * FROM t1 WHERE key2=constant ORDER BY key_part2;
* 同時(shí)使用了 ASC 和 DESC:(key_part1,key_part2建立聯(lián)合索引)
SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2 ASC;
* 用于搜索記錄的索引鍵和做 ORDER BY 的不是同一個(gè):(key1,key2分別建立索引)
SELECT * FROM t1 WHERE key2=constant ORDER BY key1;
* 如果在WHERE和ORDER BY的欄位上應(yīng)用表達(dá)式(函數(shù))時(shí),則無(wú)法利用索引來(lái)實(shí)現(xiàn)order by的優(yōu)化
SELECT * FROM t1 ORDER BY YEAR(logindate) LIMIT 0,10;
特別提示:
1mysql一次查詢只能使用一個(gè)索引。如果要對(duì)多個(gè)字段使用索引,建立復(fù)合索引。
2在ORDER BY操作中,MySQL只有在排序條件不是一個(gè)查詢條件表達(dá)式的情況下才使用索引。
本文來(lái)自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:
SELECT Seq,Rs,TotalIndex FROM TABLENAME; -- 正常查詢
SELECT Seq,Rs,TotalIndex FROM Tablename Order By cast(TotalIndex As Decimal(32,16)) Desc ; -- 強(qiáng)制將 TotalIndex 字段轉(zhuǎn)換為浮點(diǎn)型(32位長(zhǎng)度,16位小數(shù)位) Desc 倒序{降序} / Asc 正序{增序}
--特別說(shuō)明:如果數(shù)據(jù)量較大,請(qǐng)先按條件篩選出數(shù)據(jù)結(jié)果后,,再最外層Sql語(yǔ)句上去排序,這樣的處理方式不會(huì)進(jìn)行全表掃描,示例如下
Select t1.seq,t1.rs,t1.totalindex from (
SELECT Seq,Rs,TotalIndex FROM Tablename where Rs = ?
) t1 Order By cast(t1.totalindex As Decimal(32,16)) Desc ;
文章標(biāo)題:mysql8怎么降序索引 mysql索引升序
分享鏈接:http://chinadenli.net/article44/hjidhe.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)網(wǎng)站制作、軟件開發(fā)、網(wǎng)站制作、虛擬主機(jī)、商城網(wǎng)站、靜態(tài)網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)