共計 828 個字符,預計需要花費 3 分鐘才能閱讀完成。
這篇文章給大家分享的是有關 Oracle 中復合索引與空值的索引怎么用的內容。丸趣 TV 小編覺得挺實用的,因此分享給大家做個參考,一起跟隨丸趣 TV 小編過來看看吧。
在 QQ 群里討論一個 SQL 優化的問題,語句大致如下:
select A,min(B) from table group by A;--A,B 都沒有 not null 約束,A 列無空值,B 列有空值。-- 存在復合索引 IX_TEST(A,B)
于是手動測試,環境采用 Oracle 自帶的 scott 用戶下的 emp 表。
1. 首先查看如下語句的執行計劃(此時表只有主鍵索引):
2. 添加 IX_TEST(deptno,comm) 后查看執行計劃:
發現依然是全表掃描。
3. 為 deptno 列添加非空約束后再次查看執行計劃:
4. 總結:
Btree 索引是不存儲空值的,這個是所有使用 Btree 索引的數據庫的共同點。
在本例中我們創建了 deptno,comm 的符合索引。如果 deptno 沒有非空約束,那么說明有的 record 不會出現在索引中,此時想要找到 min(comm) 就必須回表才能確定 deptno 為 null 的行是否有 comm 的值。此時優化器認為全表掃描比掃描索引再回表更為合理,因此選擇全表掃描。
當我們添加了非空約束后,deptno 不可能為空,因此索引的 key 值數等于表總行數,另一列 comm 即便為空也不影響 min() 取值,只需要掃描索引即可得到所需結果,此時優化器選擇索引掃描。
而在 Mysql 中無論復合索引首列是否存在非空約束,都會使用索引,deptno 為 null 的會全部分在一組取 min(comm),可能是 Mysql 的 BTREE 索引與 Oracle 的有所不同,使得首列為空都可以無需回表。
最后:Oracle 的列能添加非空約束的一定要添加。
感謝各位的閱讀!關于“Oracle 中復合索引與空值的索引怎么用”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!