如何提高 select 超过 1000 万条记录 table 的查询性能?

How improve select query performance in 10M+ records table?

我有一个超过 1000 万行的 table,我使用带有绑定变量的简单查询(在我的例子中,我无法通过主键 ID 进行搜索)。

table 看起来像这样:

Col1   Col2   Col3   Col4   Col5   Col6

查询就像

select distinct col1  
from table ;

select distinct col2 
where col1 = :bind ;

select distinct col3 
where col1 = :bind1 and col2 = :bind2 ;
.
.

select distinct col6 
where col1 = :bind1 and col2 = :bind2 and col3 = :bind3
  and col4 = :bind4 and col5 = :bind5 

所有这些查询的结果都不大 - 最多少于 100 条记录 - 但性能太慢。

如何改进?

您可以在 (col1, col2, col3, col4, col5) 上添加索引。这可用于所有查询:

create index idx_t_5 on t(col1, col2, col3, col4, col5);

如果这不可能并且列具有相同的类型,那么您可以使用 Oracle 12c+ 中的横向连接将其合并为一个查询:

select distinct which, col
from t cross apply
     (select 'col1' as which, t.col1 as col from dual union all
      select 'col2', t.col2 from dual where t.col2 = :bind2 union all
      . . .
     ) t
where col1 = :bind1;

这将只扫描一次 table,这是一个性能改进。

一般情况下,这样建索引:

  1. 包括所有 WHERE 列,这些列针对 = 的常量进行了测试。 (到目前为止,您的所有示例都符合此标准。)列可以按任何顺序排列。
  2. (这是最优的。)在 INDEX 末尾包含 SELECT 项,任意顺序。这使得索引 "covering"(除非它比描述的更复杂)。
  3. 请注意,末尾的额外列会造成轻微负担,但无害。

"composite" INDEX(col1, col2, col3, col4, col5, col6) 恰好匹配这两个 'rules' 如果你有一些 SELECT 这有点不同,请展示给我们;我们也许可以帮助您为它建立另一个索引。