一次分頁查詢的優化
SELECT a.ID,
GMT_MODIFIED,
GMT_CREATE,
NAME,
SOURCE,
SIGN,
CATEGORY_ID,
DESCRIPTION,
DETAILS,
KEYWORDS,
PIC_URLS,
STATUS,
KEY_VALUE1,
KEY_VALUE2,
KEY_VALUE3
FROM (SELECT *
FROM (SELECT id, rownum linenum
FROM (SELECT *
FROM (SELECT id
FROM alibaba.SPU
WHERE CATEGORY_ID = 1043726
AND BITAND(Nvl(SIGN, 0), 1) = 1
ORDER BY ID DESC)
WHERE rownum < 10001)
WHERE rownum <= 200)
WHERE linenum >= 0) a,
alibaba.spu b
WHERE a.id = b.id;
同事問的一個問題,說這個SQL查詢很慢,該如何優化?
Index Column Col Column
Name Name Pos Details
------------------------------ ------------------------------ ---- ------------------------
SPU_CKKKSSGGNI_IND CATEGORY_ID 1 NUMBER(22)
KEY_VALUE1 2 VARCHAR2(256)
KEY_VALUE2 3 VARCHAR2(256)
KEY_VALUE3 4 VARCHAR2(256)
STATUS 5 VARCHAR2(16)
SIGN 6 NUMBER(22)
GMT_CREATE 7 DATE NOT NULL
GMT_MODIFIED 8 DATE NOT NULL
NAME 9 VARCHAR2(128)
ID 10 NUMBER(22) NOT NULL
查詢謂詞出現了CATEGORY_ID,SIGN(函式).排序的條件是ID,ID也在索引裡。
由於SIGN上使用了函式,因此這個欄位只能在索引裡過濾。CATEGORY_ID = 1043726的值有非常多。
由於我們的查詢是分頁查詢,如果能在索引裡完成分頁,效率應該還是可以的。
可是遺憾的是,這個查詢並不能在索引裡完成分頁。
因為雖然ID包含在了索引裡,可是ID的前面還有很多其他的鍵值包含在索引裡。
對於(CATEGORY_ID,SIGN)為等值查詢的情況下,如果索引的組合為
(CATEGORY_ID,SIGN,ID),ID一定是有序的。
但是如果索引的組合是
(CATEGORY_ID,SIGN,XX,ID),那麼ID就不是有序的了。需要完全掃描相關索引排序後,再取出前TOP N條。
因此效率就差了。
解決的辦法很簡單,就是建立一個索引(CATEGORY_ID,SIGN,ID)就可以了。
還有就是同事說建立索引要對ID加上DESC關鍵字(CATEGORY_ID,SIGN,ID DESC),因為ORDER BY ID DESC.
其實這個是沒必要的,ORACLE可以完成這種轉換。執行計劃部分會出現INDEX RANGE SCAN DESCENDING的執行方式。
GMT_MODIFIED,
GMT_CREATE,
NAME,
SOURCE,
SIGN,
CATEGORY_ID,
DESCRIPTION,
DETAILS,
KEYWORDS,
PIC_URLS,
STATUS,
KEY_VALUE1,
KEY_VALUE2,
KEY_VALUE3
FROM (SELECT *
FROM (SELECT id, rownum linenum
FROM (SELECT *
FROM (SELECT id
FROM alibaba.SPU
WHERE CATEGORY_ID = 1043726
AND BITAND(Nvl(SIGN, 0), 1) = 1
ORDER BY ID DESC)
WHERE rownum < 10001)
WHERE rownum <= 200)
WHERE linenum >= 0) a,
alibaba.spu b
WHERE a.id = b.id;
同事問的一個問題,說這個SQL查詢很慢,該如何優化?
Index Column Col Column
Name Name Pos Details
------------------------------ ------------------------------ ---- ------------------------
SPU_CKKKSSGGNI_IND CATEGORY_ID 1 NUMBER(22)
KEY_VALUE1 2 VARCHAR2(256)
KEY_VALUE2 3 VARCHAR2(256)
KEY_VALUE3 4 VARCHAR2(256)
STATUS 5 VARCHAR2(16)
SIGN 6 NUMBER(22)
GMT_CREATE 7 DATE NOT NULL
GMT_MODIFIED 8 DATE NOT NULL
NAME 9 VARCHAR2(128)
ID 10 NUMBER(22) NOT NULL
查詢謂詞出現了CATEGORY_ID,SIGN(函式).排序的條件是ID,ID也在索引裡。
由於SIGN上使用了函式,因此這個欄位只能在索引裡過濾。CATEGORY_ID = 1043726的值有非常多。
由於我們的查詢是分頁查詢,如果能在索引裡完成分頁,效率應該還是可以的。
可是遺憾的是,這個查詢並不能在索引裡完成分頁。
因為雖然ID包含在了索引裡,可是ID的前面還有很多其他的鍵值包含在索引裡。
對於(CATEGORY_ID,SIGN)為等值查詢的情況下,如果索引的組合為
(CATEGORY_ID,SIGN,ID),ID一定是有序的。
但是如果索引的組合是
(CATEGORY_ID,SIGN,XX,ID),那麼ID就不是有序的了。需要完全掃描相關索引排序後,再取出前TOP N條。
因此效率就差了。
解決的辦法很簡單,就是建立一個索引(CATEGORY_ID,SIGN,ID)就可以了。
還有就是同事說建立索引要對ID加上DESC關鍵字(CATEGORY_ID,SIGN,ID DESC),因為ORDER BY ID DESC.
其實這個是沒必要的,ORACLE可以完成這種轉換。執行計劃部分會出現INDEX RANGE SCAN DESCENDING的執行方式。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22034023/viewspace-718478/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 分頁查詢優化優化
- MySQL分頁查詢優化MySql優化
- MySQL——優化巢狀查詢和分頁查詢MySql優化巢狀
- 關於分頁查詢的優化思路優化
- MySQL分優化之超大頁查詢MySql優化
- 資料庫全表查詢之-分頁查詢優化資料庫優化
- mysql大資料量分頁查詢方法及其優化MySql大資料優化
- 記一次分頁優化優化
- 效能優化之分頁查詢優化
- 一次簡單的分頁優化優化
- 資料量很大,分頁查詢很慢,該怎麼優化?優化
- 涉及子查詢sql的一次優化SQL優化
- MySQL查詢中分頁思路的優化BFMySql優化
- MySQL的分頁查詢MySql
- Oracle的分頁查詢Oracle
- Lucene的分頁查詢
- 如何優雅地實現分頁查詢
- Greenplum點查詢的優化(分佈鍵)優化
- 一次系統檢視查詢的優化優化
- 關於分頁查詢的最佳化思路
- Elasticsearch 分頁查詢Elasticsearch
- ssh 分頁查詢
- oracle分頁查詢Oracle
- 海量資料庫的查詢優化及分頁演算法方案資料庫優化演算法
- 一次內鏈子查詢優化 2優化
- 一次內鏈子查詢優化 1優化
- 左百分號模糊查詢的優化優化
- 分庫分表後的分頁查詢
- MySQL 千萬資料庫深分頁查詢優化,拒絕線上故障!MySql資料庫優化
- 海量資料庫的查詢優化及分頁演算法方案(轉)資料庫優化演算法
- 查詢優化優化
- ThinkPhp框架:分頁查詢PHP框架
- NET 集合分頁查詢
- MySQL 多表查詢分頁MySql
- 分頁查詢重構
- Oracle分頁查詢格式Oracle
- MySQL 的查詢優化MySql優化
- 記一次 Golang 資料庫查詢元件的優化。Golang資料庫元件優化