优化Oracle 10密集唯一索引上的SELECT查询

时间:2009-05-29 12:59:15

标签: sql oracle optimization

我在Oracle 10中有一个表格,其结构如下

Create Table Bookmarks(  
    BOOKMARKID NUMBER(10,0) NOT NULL PRIMARY KEY,
    URL VARCHAR2(4000 CHAR) NOT NULL UNIQUE
)

URL具有唯一约束集,因此具有唯一索引。此表中有大约100万条记录。我必须经常检查表中是否已存在书签。我发出以下查询

Select bookmarkid from Bookmarks where URL='<some url>'

问题在于随着记录数量的增加,性能下降。现在,当查询URL很长时,返回书签ID需要更长的时间。在解释计划中,查询确实在URL列上使用唯一索引。有关改善响应时间的建议吗?

4 个答案:

答案 0 :(得分:3)

您通常会使用哈希索引。在mssql中,我会创建一个像CRC(url)那样的持久计算列。然后当你想要检查是否存在时,你会查找WHERE crc('some url')= PersistedCrcColumn AND URL ='some url'

您必须在crc检查中包含原始检查,因为您偶尔可以获得CRC冲突。

编辑 - 将上面的描述从“哈希查找”更改为“哈希索引”以避免混淆。有些dbs将哈希索引作为第一类索引,我不相信oracle会这样做(我知道mssql没有)。如果内在不支持,则上述方法是手动实现它。

答案 1 :(得分:3)

制作包含bookmarkid列的索引。 像这样:

create IX on bookmarks (url, bookmarkid);

答案 2 :(得分:2)

MD4计算URL索引并将其分配给触发器:

:new.HASH := DBMS_CRYPTO.hash(UTL_RAW.cast_to_raw(:new.url), 1)

在此列上创建索引并按哈希值搜索。

请勿忘记GRANT EXECUTE DBMS_CRYPTO对拥有触发器的用户。

MD4是最快的散列算法,这就是为什么它广泛用于密码强度不重要的地方。

答案 3 :(得分:2)

检查执行计划是否在索引上使用UNIQUE扫描,而不是完整/快速完整/范围扫描。 你可能从http://www开始有很多URLS。 (也许还有很多领先的价值观),这并不理想。如果可以,请在ORA_HASH(url)上创建一个非唯一的基于函数的索引,并将其添加到查询中。它会给出一个小得多的索引值,并且具有更好的值扩展。 如果无法更改查询,请尝试使用REVERSE重新创建索引。

它对索引值的大小没有帮助,但可能会更好地传播它。