我在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列上使用唯一索引。有关改善响应时间的建议吗?
答案 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重新创建索引。
它对索引值的大小没有帮助,但可能会更好地传播它。