sql在不新增索引的前提下下的解決思路

2021-10-11 20:50:47 字數 1305 閱讀 3329

二、非資料庫優化法,使用redis

目前有乙個sql,需要查出某個客戶的前100次消費記錄,訂單表有幾億資料,且只有主鍵id自增索引,不能改造表結構。如何解決?需要從資料庫層面與非資料途徑兩方面給出兩種解決方案。sql如下:

select * from order where user_id = 1 order by created_time desc limit 100

將order by created_time替換為order by desc,原因為只有id有索引。

看一下區別:

看一下 order by created_time

可以看到題目給的sql是超級慢的,全表所描+檔案排序,上億級別資料幾分鐘都執行不完。

看一下 order by id desc

可以看出是使用到索引的,且沒有file sort,一定要避免file sort,超級慢的原因之一就是檔案排序

直接使用where user_id = 112233 order by id desc limit 10,雖然比原sql強,但由於使用了排序,依然會慢。

這時我們可以考慮利用id主鍵索引,從後往前查,先查到這個使用者的最後一筆訂單的id,然後使用where id < *** and user_id = 112233。

找了一張300萬資料的表:

原sql處理速度 where user_id = 112233 order by created_time desc limit 1:

第一次優化:

where user_id = 112233 order by id desc limit 1

使用最大的id,查出剩餘9條最新消費訂單資料where id < *** and user_id = 112233 limit 9:

可以使用redis的list結構實現佇列,為每個使用者實時維護前n筆消費的order_id

redis結構:key:user_id value:list結構,儲存order_id

在儲存order_id時需要注意併發的情況,多個使用者同時下單,操作redis可能導致多插,考慮使用redis事物+樂觀鎖。redis事物可以保證一致性與隔離性,但由於沒有回滾機制,不能保證原子性,可以使用樂觀鎖來彌補。

// cas樂觀鎖變數

boolean cas = false;

// 失敗後自旋次數

in i = 0;

// 允許自旋10次

while(i <= 10)

if(cas === false)

怎麼在不破壞資料的前提下重新劃分分割槽?

這個操作必須要求你的檔案系統是 ntfs 的。fat32檔案系統不行哦。右鍵點那個盤 屬性 常規選項卡上 檔案系統會顯示你的檔案系統。2.打上下面這個命令,然後按回車執行 x 代表你的碟符,用你具體的碟符字母替換掉 3.等上幾分鐘,看到確認資訊後關閉視窗。開始操作 從現有分割槽中割一塊出來做個分割槽...

怎樣在不寫正則的前提下提取網頁的標題和內容

怎樣在不寫正則的前提下提取網頁的標題和內容?字串擷取 先用indexof tittle 取得對應字串在文中的位置 再結合使用substring 等字串擷取函式,不用正則很麻煩 而且不通用 而且效率低!標題不用正則也可以切出來,內容是指的那些東西?純文字麼?用遞迴過濾所有的html.雖然可以過濾所有h...

二維 多維vector在未知維度的前提下的賦值操作

在很多時候,類中二維陣列的維度往往無法提前知道,因此需要動態地分配空間。使用new運算子是其中的乙個解決方案,但是操作不當往往會造成記憶體溢位 洩漏。使用stl的vector可以避免這個麻煩。例如,我在乙個類中定義了乙個資料成員a為二維int型別vector class a 在a的成員函式creat...