以高性能的方式从Oracle DB中选择一个随机行

时间:2018-01-09 12:20:07

标签: database oracle database-performance

使用: Oracle Database 12c企业版12.1.0.2.0版

我正在尝试获取随机行。正如其他stackoverflow问题中所建议的那样,我使用DBMS_RANDOM.VALUE这样 -

SELECT column FROM
( SELECT column 
  FROM table
  WHERE COLUMN_VALUE = 'Y' -- value of COLUMN_VALUE
  ORDER BY dbms_random.value 
)
WHERE rownum <= 1

但是当请求数量增加时,此查询不具备性能。 所以我正在寻找替代方案。

SAMPLE对我不起作用,因为通过该子句拾取的样本将没有与我的WHERE子句匹配的数据集。查询看起来像这样 -

SELECT column FROM table SAMPLE(1) WHERE COLUMN_VALUE = 'Y'

因为SAMPLE在我的WHERE子句之前应用,所以大部分时间都没有返回数据。

P.S:我可以将逻辑的某些部分移到应用层(虽然我绝对不会寻找建议将所有内容加载到内存中的答案)

1 个答案:

答案 0 :(得分:2)

性能问题包括两个方面:

  • 使用column_value = 'Y'

  • 选择数据
  • 对此子集进行排序以获取随机记录

您没有说明column_value = 'Y'表格的子集是大还是小。这很重要,将推动您的战略。

如果有大量记录 column_value = 'Y',请使用SAMPLE将行限制为已排序。 你是对的,这可能导致空结果 - 在这种情况下重复查询(你可以另外添加一个逻辑,增加样本百分比,以避免很多重复)。 这将在您对数据样本进行排序时提高性能

select id from (
select id from tt SAMPLE(1) where column_value = 'Y' order by  dbms_random.value )
where rownum <= 1; 

如果只有少数 column_value = 'Y'的记录在此列(或单独的分区)上定义索引 - 这将启用对记录的有效访问。使用order by dbms_random.value方法。 Sort不会降低少量行的性能。

select id from (
select id from tt where column_value = 'Y' order by  dbms_random.value )
where rownum <= 1;

基本上两种方法都将排序的行保持在较小的尺寸。第一种方法执行与 FULL TABLE SCAN 相当的表格访问,第二种方法对选定的column_value执行 INDEX ACCESS