spl的特徵之一是資料有序,適當地利用位置,可以顯著提高效能。讓我們先從乙個典型場景開始,逐步掌握利用位置的各種技巧。
快速查詢
對排序後的資料進行二分查詢,可以獲得較高的效能,但有些演算法需用到原始順序,看上去似乎不該再排序。比如下面的案例:
performanceranking.txt有三個字段,分別是empid(銷售員編號)、dep(部門名稱)、amount(銷售額)。該檔案記錄著各部門各銷售員本季度的業績排名,已按銷售額逆序存放,現在需根據指定的銷售員id,計算出:他應當再增加多少銷售額,才能提高業績排名。如果該員工已經是第1名,則無需增加銷售額。
本演算法需要用排名高一位的銷售員的銷售額,減去該銷售員的銷售額,即對原始資料做相對位置計算。既然要用到原始順序,似乎就不該再排序,否則兩者難以互轉,而且其他演算法可能用到原始資料。這種思路下會把指令碼寫成這樣:
上述指令碼沒有對資料排序,所以不能進行二分查詢,效能不高。
事實上,我們可以在保留原始資料的前提下,利用位置進行排序,從而提高查詢效能。指令碼如下:
a5:函式psort只獲得排序後記錄在原資料中的位置,並不會對原資料真正排序。
a6:利用opos製造乙份排序後的資料。注意,此時原資料不受影響,而且opos可以作為排序後資料index和原始資料之間互轉的橋梁。
a7:對排序後的資料做二分查詢,並轉回原始資料中對應的記錄序號。
為了驗證利用位置之前、之後兩種演算法的效能差別,可以隨機取出銷售員編號做引數,用迴圈模擬大量訪問,並分別執行兩種演算法。如下:
可以看到,利用位置後效能提高幾十倍。例子中資料量較少,隨著資料量的增加,效能差距會急劇拉大,這是因為遍歷查詢的時間複雜度為線性,而二分查詢為對數。
快速對齊
函式align可將資料按序列對齊,比如輸入條件:=porderlist= [10250,10247,10248,10249,10251],將訂單明細按該列表對齊,求每個訂單的金額小計。**如下:
但上述寫法沒有利用位置,效能因此不高。要想提高效能,可以將序列排序(手工建立索引表),再用二分法對齊,最後恢復為原順序,**如下:
a2-a3:手工建立索引表。
a4:將訂單明細表與訂單列表對齊,求出金額小計。由於索引表有序,因此可用二分法對齊,即@b選項。
a5:將a4按原位置調整,與porderlist的順序保持一致。函式inv可按指定位置調整成員,這裡按原位置調整成員,相當於恢復成原位置。
對利用位置前後的兩種演算法,模擬大訪問量測試,可以看到效能提公升顯著:
有序資料批量查詢
有時要對有序資料進行批量查詢,比如porderlist=[10877,10588,10611,11037,10685],請統計符合該列表的訂單的運貨費合計,**可以這樣寫:
解釋:函式pos和select配合,可實現批量查詢。其中函式pos可返回某個值在序列中的位置,如該值不在序列中,則返回null。函式select用於查詢,當條件非null且非false時,可返回當前記錄。
但上述**沒有利用位置,所以效能不高。
應當注意到,訂單記錄是有序的,所以可以用二分法取得符合條件的訂單位置,再用位置取記錄並計算。具體**如下:
a1.(orderid)可取得orderid列,pos@b可針對有序資料,用二分法快速取得成員位置。a6按位置取資料。
對利用位置前後的兩種演算法,模擬大訪問量測試,可以看到效能提公升顯著:
效能優化 Limit查詢的優化
limit常用於分頁處理,時長會伴隨order by從句使用,因此大多時候回使用filesorts這樣會造成大量的io問題。例子 需求 查詢影片id和描述資訊,並根據主題進行排序,取出從序號50條開始的5條資料。select film id,description from sakila.film ...
查詢效能的優化 前言
上一章,我們解釋了怎樣優化schema.這是高效能的乙個必要條件。但是僅僅考慮schema也是不夠的 你也需要設計你的查詢。如果你的查詢很差,即使schema設計完美,也沒什麼用。查詢優化,索引優化,和schema優化應該一起齊頭並進的。隨著你在mysql中獲得了優化查詢的經驗,你也會明白怎樣設計s...
MySQL單錶百萬資料記錄分頁效能優化技巧
自己的乙個 由於單錶的資料記錄高達了一百萬條,造成資料訪問很慢,google分析的後台經常報告超時,尤其是頁碼大的頁面更是慢的不行 測試環境 先讓我們熟悉下基本的sql語句,來檢視下我們將要測試表的基本資訊 use infomation schema select from tables where...