我使用的是Oracle 11g,我们有3个核心表:
Customer - CUSTOMERID|DOB
CustomerName - CUSTOMERNAMEID|CustomerID|FNAME|LNAME
Address - ADDRESSID|CUSTOMERID|STREET|CITY|STATE|POSTALCODE
每张桌子上有大约6千万行,数据是美国和加拿大人口的混合。
我有一个调用Web服务的前端应用程序,他们使用姓氏和部分zip搜索。所以我的查询基本上有
where CUSTOMERNAME.LNAME = ? and ADDRESS.POSTALCODE LIKE '?%'
它们通常提供拉链的前3位数字。
地址表在所有街道/城市/州/邮政编码上都有索引,另一个在州和邮政编码上。
我确实尝试为zip专门添加一个索引,并强制oracle在我的查询中使用该索引,但这没有任何区别。
对于返回大约100行(我的分页只能一次返回100行),它需要大约30秒,这是不理想的。我能做些什么来改善它?
答案 0 :(得分:0)
问题是您正在应用的过滤器不是很有选择性,它们适用于不同的表。这对于老式的btree索引来说是坏事。如果内容非常静态,您可以尝试位图索引。更确切地说,基于函数的位图连接索引在姓氏的前三个字母和邮政编码列上的位图连接索引。这假设很少有姓氏以某些字母开头的人居住在某个邮政编码中。
CREATE BITMAP INDEX ix_customer_custname ON customer(SUBSTR(cn.lname,1,3))
FROM customer c, customername cn
WHERE c.customerid = cn.customerid;
CREATE BITMAP INDEX ix_customer_postalcode ON customer(SUBSTR(a.postalcode,1,3))
FROM customer c, address a
WHERE c.customerid = a.customerid;
如果成功,您应该会看到两个位图索引成为AND连接。执行时间应该减少到几秒钟。它不会像btree索引一样快。
<强>说明:强>
你可能不得不玩一下是否更有效地制作一个或两个索引以及该功能是否有用。
如果您决定基于函数执行此操作,则应在查询的where子句中包含完全相同的函数调用。否则将不使用索引。
DML操作会相当慢。这仅适用于具有静态数据的表。请注意,DML操作将阻止整行&#34;范围&#34;。并发DML操作将遇到问题。
响应时间可能仍然不是像BTREE索引一样的时间。
AFAIK这只适用于企业版。语法未经测试,因为我目前没有可用的企业数据库。
如果这仍然不够快,您可以使用customerid,姓氏和邮政编码创建一个物化视图,但是可以创建一个btree索引。但这也很贵。