如何提高 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,这是一个性能改进。
一般情况下,这样建索引:
- 包括所有
WHERE
列,这些列针对 =
的常量进行了测试。 (到目前为止,您的所有示例都符合此标准。)列可以按任何顺序排列。
- (这是最优的。)在
INDEX
末尾包含 SELECT
项,任意顺序。这使得索引 "covering"(除非它比描述的更复杂)。
- 请注意,末尾的额外列会造成轻微负担,但无害。
"composite" INDEX(col1, col2, col3, col4, col5, col6)
恰好匹配这两个 'rules' 如果你有一些 SELECT
这有点不同,请展示给我们;我们也许可以帮助您为它建立另一个索引。
我有一个超过 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,这是一个性能改进。
一般情况下,这样建索引:
- 包括所有
WHERE
列,这些列针对=
的常量进行了测试。 (到目前为止,您的所有示例都符合此标准。)列可以按任何顺序排列。 - (这是最优的。)在
INDEX
末尾包含SELECT
项,任意顺序。这使得索引 "covering"(除非它比描述的更复杂)。 - 请注意,末尾的额外列会造成轻微负担,但无害。
"composite" INDEX(col1, col2, col3, col4, col5, col6)
恰好匹配这两个 'rules' 如果你有一些 SELECT
这有点不同,请展示给我们;我们也许可以帮助您为它建立另一个索引。