MySQL排序機(jī)制之獲取最后10條數(shù)據(jù)的正確方法
引言
在日志分析、最新數(shù)據(jù)展示等場(chǎng)景中,我們常需獲取排序后的最后N條數(shù)據(jù)。傳統(tǒng)思維認(rèn)為直接使用ORDER BY ... DESC LIMIT N即可,但實(shí)測(cè)發(fā)現(xiàn)這種寫法在大數(shù)據(jù)量下性能驟降。本文將深入解析MySQL排序機(jī)制,揭秘高效獲取最后10條數(shù)據(jù)的科學(xué)方法。
問題本質(zhì):排序與分頁的矛盾
當(dāng)執(zhí)行SELECT * FROM table ORDER BY id DESC LIMIT 10時(shí),MySQL需完成全量排序后再截取前10條。若表有百萬級(jí)數(shù)據(jù),即使只需最后10條,仍需處理全部數(shù)據(jù)。這種"先排序后截取"的機(jī)制導(dǎo)致:
- 索引覆蓋失效,觸發(fā)臨時(shí)表創(chuàng)建
- 文件排序(filesort)消耗大量CPU/IO
- 回表操作加劇隨機(jī)IO壓力
解決方案:子查詢+雙重排序
1. 基礎(chǔ)寫法
SELECT *
FROM (
SELECT *
FROM stock_stock_day_data
WHERE stock_code = '000001'
ORDER BY id DESC
LIMIT 10
) AS sub
ORDER BY id ASC;
2. 執(zhí)行計(jì)劃分析
通過EXPLAIN可觀察到:
- 內(nèi)層查詢使用索引
idx_stock_code_id完成倒序掃描 - 外層查詢僅對(duì)10條結(jié)果進(jìn)行正序排序
- 避免全表掃描(type=range)
- 消除Using temporary/filesort
3. 性能對(duì)比
| 方案 | 執(zhí)行時(shí)間 | 臨時(shí)表 | 索引使用 |
|---|---|---|---|
| 直接排序 | 55s | 需創(chuàng)建 | 未使用復(fù)合索引 |
| 子查詢法 | 0.055s | 無需 | 使用索引覆蓋 |
性能優(yōu)化進(jìn)階
1. 索引優(yōu)化策略
- 復(fù)合索引設(shè)計(jì):創(chuàng)建
(stock_code, id)索引,使內(nèi)層查詢直接利用索引排序 - 索引提示使用:
SELECT * FROM ( SELECT * FROM stock_stock_day_data FORCE INDEX (idx_stock_code_id) WHERE stock_code = '000001' ORDER BY id DESC LIMIT 10 ) ...
- 覆蓋索引優(yōu)化:若查詢字段固定,創(chuàng)建包含所有字段的復(fù)合索引
2. 執(zhí)行計(jì)劃調(diào)優(yōu)
通過EXPLAIN識(shí)別潛在問題:
type=ALL表示全表掃描,需優(yōu)化索引Extra=Using filesort提示需優(yōu)化排序字段索引rows值過大說明掃描數(shù)據(jù)過多
3. 服務(wù)器參數(shù)調(diào)整
- 增大
sort_buffer_size減少磁盤排序 - 調(diào)整
tmp_table_size避免臨時(shí)表磁盤存儲(chǔ) - 優(yōu)化
innodb_buffer_pool_size提升緩存命中率
特殊場(chǎng)景處理
1. 超大結(jié)果集優(yōu)化
使用變量緩存法避免全量排序:
SET @rownum := 0;
SELECT *
FROM (
SELECT *, @rownum := @rownum + 1 AS rownum
FROM stock_stock_day_data
WHERE stock_code = '000001'
ORDER BY id DESC
) t1
WHERE rownum <= 10
ORDER BY id ASC;
2. 高并發(fā)場(chǎng)景優(yōu)化
- 避免長(zhǎng)事務(wù)導(dǎo)致的鎖競(jìng)爭(zhēng)
- 使用連接池控制并發(fā)度
- 分區(qū)表優(yōu)化(按stock_code分區(qū))
總結(jié)
高效獲取最后10條數(shù)據(jù)需遵循"先定位后排序"原則:
- 使用子查詢快速定位目標(biāo)數(shù)據(jù)集
- 通過復(fù)合索引實(shí)現(xiàn)索引覆蓋
- 外層查詢僅對(duì)結(jié)果集進(jìn)行二次排序
- 結(jié)合執(zhí)行計(jì)劃分析持續(xù)優(yōu)化
通過索引優(yōu)化、執(zhí)行計(jì)劃調(diào)優(yōu)、服務(wù)器參數(shù)調(diào)整三管齊下,可使查詢性能提升千倍。掌握這些核心方法,即可在百萬級(jí)數(shù)據(jù)中實(shí)現(xiàn)毫秒級(jí)響應(yīng),真正實(shí)現(xiàn)"大數(shù)據(jù),小延遲"的極致體驗(yàn)。
以上就是MySQL排序機(jī)制之獲取最后10條數(shù)據(jù)的正確方法的詳細(xì)內(nèi)容,更多關(guān)于MySQL排序后取最后10條數(shù)據(jù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Windows下MySQL8.0.11社區(qū)綠色版安裝步驟圖解
在本教程中使用MySQL最新的MySQL服務(wù)8.0.11的社區(qū)綠色版本進(jìn)行安裝,綠色版為zip格式的包,安裝步驟分為四大步驟,具體哪四大步驟大家跟隨腳本之家小編一起學(xué)習(xí)吧2018-05-05
mysql case when group by 實(shí)例詳解
這篇文章主要介紹了mysql 中類似php switch case 的語句,需要的朋友可以參考下2018-01-01
mysql修改數(shù)據(jù)庫默認(rèn)路徑無法啟動(dòng)問題的解決
這篇文章主要給大家介紹了關(guān)于mysql修改數(shù)據(jù)庫默認(rèn)路徑無法啟動(dòng)問題的解決方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-11-11
MySql8設(shè)置遠(yuǎn)程連接的實(shí)戰(zhàn)記錄
與SQL Server類似,MySQL在需要遠(yuǎn)程操縱其他電腦時(shí),也需要對(duì)其做遠(yuǎn)程連接的相應(yīng)設(shè)置,下面這篇文章主要給大家介紹了關(guān)于MySql8設(shè)置遠(yuǎn)程連接的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2022-04-04

