Oracle 是一款廣泛應(yīng)用于企業(yè)級(jí)數(shù)據(jù)庫(kù)管理系統(tǒng)的軟件。在使用Oracle 進(jìn)行數(shù)據(jù)庫(kù)管理的過(guò)程中,索引是一項(xiàng)非常重要的功能。通過(guò)創(chuàng)建合適的索引來(lái)提高查詢(xún)效率,加快查詢(xún)速度。然而,即便是在有索引的情況下,查詢(xún)依然有可能不走索引。
我們來(lái)看一個(gè)例子:
SELECT * FROM customers WHERE last_name = ‘Smith’;
如果 customers 表上有針對(duì) last_name 列的索引,那么查詢(xún)就會(huì)走索引,查詢(xún)速度也會(huì)非常快。但是,如果 last_name 列的數(shù)據(jù)比較少,比如全表只有不到 1% 的數(shù)據(jù)是 last_name 為 'Smith',那么 Oracle 就很可能不使用索引。
這是因?yàn)樵谶@種情況下,如果使用索引,Oracle 需要借助索引樹(shù)來(lái)找到匹配項(xiàng),但是如果數(shù)據(jù)比較少,那么 Oracle 在查詢(xún)數(shù)據(jù)時(shí)就會(huì)選擇全表掃描,因?yàn)樗J(rèn)為經(jīng)過(guò)索引查找的時(shí)間比全表掃描到這條數(shù)據(jù)的時(shí)間還要長(zhǎng)。
更進(jìn)一步地,以下幾種情況也有可能導(dǎo)致不走索引:
1.使用計(jì)算表達(dá)式查詢(xún)
SELECT * FROM customers WHERE salary * 12 >10000;
這種情況 Oracle 不會(huì)使用索引,因?yàn)樗枰葘?duì) salary 再進(jìn)行計(jì)算,索引不支持計(jì)算。
2.使用 or 語(yǔ)句查詢(xún)
SELECT * FROM customers WHERE last_name = ‘Smith’ OR first_name = ‘John’;
這種情況雖然 last_name 列上有索引,但 Oracle 仍然不會(huì)使用索引,因?yàn)樯婕暗交蛘Z(yǔ)句,需要掃描整張表。
3.使用 like 語(yǔ)句查詢(xún)
SELECT * FROM customers WHERE last_name like ‘Sm%’;
這種情況雖然 last_name 列上有索引,但是 Oracle 不會(huì)使用索引,因?yàn)?like 語(yǔ)句導(dǎo)致索引不生效。
總之,這些情況下 Oracle 會(huì)放棄使用索引而選擇全表掃描。這也就是為什么我們要合理地設(shè)計(jì)索引,以避免不走索引。