Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql Oracle10密集唯一索引上的SELECT查询优化_Sql_Oracle_Optimization - Fatal编程技术网

Sql Oracle10密集唯一索引上的SELECT查询优化

Sql Oracle10密集唯一索引上的SELECT查询优化,sql,oracle,optimization,Sql,Oracle,Optimization,我在Oracle10中有一个表,其结构如下 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=

我在Oracle10中有一个表,其结构如下

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>'

问题是,随着记录数量的增加,性能也随之下降。现在,返回书签id的时间要长得多,特别是当查询URL很长时。在解释计划中,查询在URL列上使用唯一索引。有没有改进响应时间的建议?

您通常会为此使用哈希索引。在mssql中,我将创建一个持久化的计算列,它与CRCurl类似。然后,当您想要检查是否存在时,您可以在其中查找crc'someURL'=PersistedCrcColumn和url='someURL'

您必须将原始检查包括在crc检查中,因为有时会发生crc冲突


编辑-将上面的描述从“哈希查找”更改为“哈希索引”,以避免混淆。有些数据库有哈希索引作为一级索引,我不相信oracle有,我知道mssql没有。如果本质上不支持它,则上述方法是您手动实现它的方式。

您通常会为此使用哈希索引。在mssql中,我将创建一个持久化的计算列,它与CRCurl类似。然后,当您想要检查是否存在时,您可以在其中查找crc'someURL'=PersistedCrcColumn和url='someURL'

您必须将原始检查包括在crc检查中,因为有时会发生crc冲突

编辑-将上面的描述从“哈希查找”更改为“哈希索引”,以避免混淆。有些数据库有哈希索引作为一级索引,我不相信oracle有,我知道mssql没有。如果本质上不支持,则上述方法是手动实现的方法。

计算URL的MD4索引,并将其分配到触发器中:

:new.HASH := DBMS_CRYPTO.hash(UTL_RAW.cast_to_raw(:new.url), 1)
在此列上创建索引并按哈希值进行搜索

不要忘记向拥有触发器的用户授予EXECUTE on DBMS_CRYPTO

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

计算URL的MD4索引并在触发器中分配:

:new.HASH := DBMS_CRYPTO.hash(UTL_RAW.cast_to_raw(:new.url), 1)
在此列上创建索引并按哈希值进行搜索

不要忘记向拥有触发器的用户授予EXECUTE on DBMS_CRYPTO


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

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

create IX on bookmarks (url, bookmarkid);

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

create IX on bookmarks (url, bookmarkid);

检查执行计划是否在索引上使用唯一扫描,而不是全/快速全/范围扫描。 你可能有很多URL都是从开始的。也许还有更多的主导价值观,这并不理想。如果可以,可以在ORA_HASHurl上创建一个基于非唯一函数的索引,并将其添加到查询中。它将给出一个更小的索引值,并具有更好的值分布。 如果无法更改查询,请尝试使用重新创建索引


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

检查执行计划是否对索引使用唯一扫描,而不是全/快速全/范围扫描。 你可能有很多URL都是从开始的。也许还有更多的主导价值观,这并不理想。如果可以,可以在ORA_HASHurl上创建一个基于非唯一函数的索引,并将其添加到查询中。它将给出一个更小的索引值,并具有更好的值分布。 如果无法更改查询,请尝试使用重新创建索引


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

是否需要触发器?为什么不是基于函数的索引?@tuinstoel:UTL_RAW.cast_to_RAW不是确定性的。啊,它应该是确定性的,不是吗?你可以创建一个包装函数myhash来包装dbms_crypto并声明它是确定性的。这是一个丑陋的解决方案/解决方案,触发器更好。我会选择ORA_HASH,但不确定哈希算法的性能,但避免PL/SQL和SQL之间的切换可能会超过这一点。是否需要触发器?为什么不是基于函数的索引?@tuinstoel:UTL_RAW.cast_to_RAW不是确定性的。啊,它应该是确定性的,不是吗?你可以创建一个包装函数myhash来包装dbms_crypto并声明它是确定性的。这是一个丑陋的解决方案/解决方案,触发器更好。我会选择ORA_HASH,但不确定哈希算法的性能,但避免PL/SQL和SQL之间的切换可能会超过这一点。我投票支持Dmitry的答案——如果答案不明显,在索引中包含bookmarkid列,Oracle无需访问表段块以重新检索
查看信息-仅访问索引。如果书签表是相对静态的,那么将其创建为一个物联网索引的有组织的表将是一种类似的方法。我投票支持Dmitry的答案——如果答案不明显,在索引中包含bookmarkid列可以消除Oracle访问表段块以检索信息的需要-只访问索引。如果书签表是相对静态的,那么将其创建为一个物联网索引的有组织的表将是一种类似的方法。