Oracle 11G如何将多值存储到一个列,但可以获得确定的性能

发布于 2025-02-10 07:47:55 字数 482 浏览 2 评论 0原文

嗨,

我的数据库是oracle11g。由于某种原因,我需要在第1列中存储一个或几个值。在这种情况下,我使用'||'作为定界线。因此,SQL查询正在尝试回答,例如,第1列中的值310-G01-000-000-000?

我想要一个用于Oracle 11G的解决方案以增强查询性能吗?我知道PostgreSQL列可以存储一个数组,并且有数组索引。但是对于Oracle,我不知道。

我的想法是使用Regexp_substr生成列表,并且在Regexp_substr上使用函数索引可能会起作用吗?

请让我知道将多值存储到一列的最佳实践以及快速查询它的方法吗?

多谢 j

Table definition

Hi,

My database is Oracle11g. For some reason, I need to store one or several values in column1. In this case I use '||' as a delimiter. So the sql query is trying to answer, e.g. if value 310-G01-000-000-000 in column1?

I want a solution, for Oracle 11g, to enhance the query performance? I know that PostgreSQL column can store an array, and there is index for array. But for Oracle, I don't know.

On of my thought is using REGEXP_SUBSTR to generate a list, and use function index on REGEXP_SUBSTR may work?

Please let me know the best practice to store multi values to one column and the way to query it quickly?

Thanks a lot
J

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

装迷糊 2025-02-17 07:47:55

如果您想要性能,则不要将划界值存储在列中。

如果您无法避免它,则只需使用简单的字符串函数(比正则表达式快的数量级)来检查是否存在子弦匹配:

SELECT *
FROM   test_table
WHERE  '||' || column1 || '||' LIKE '%||' || :search_value || '||%';

或:

SELECT *
FROM   test_table
WHERE  INSTR('||' || column1 || '||', '||' || :search_value || '||') > 0;

但是:但是,

表:

CREATE TYPE string_list IS TABLE OF VARCHAR2(19);

CREATE TABLE test_table (
  id      VARCHAR2(10),
  column1 string_list
) NESTED TABLE column1 STORE AS test_table__column1;

然后:

INSERT INTO test_table (
  id,
  column1
) VALUES (
  'abc',
  string_list('310-G01-000-000-000', '310-G04-000-000-000','310-G04-000-000-001')
);

您可以使用嵌套 值使用收集操作员的成员:

SELECT id
FROM   test_table
WHERE  '310-G01-000-000-000' MEMBER OF column1;

db<> fiddle 此处

If you want performance then don't store delimited values in a column.

If you cannot avoid it then just use simple string functions (which are an order of magnitude faster than regular expressions) to check if there is a sub-string match:

SELECT *
FROM   test_table
WHERE  '||' || column1 || '||' LIKE '%||' || :search_value || '||%';

or:

SELECT *
FROM   test_table
WHERE  INSTR('||' || column1 || '||', '||' || :search_value || '||') > 0;

However

You could use a nested table:

CREATE TYPE string_list IS TABLE OF VARCHAR2(19);

CREATE TABLE test_table (
  id      VARCHAR2(10),
  column1 string_list
) NESTED TABLE column1 STORE AS test_table__column1;

Then:

INSERT INTO test_table (
  id,
  column1
) VALUES (
  'abc',
  string_list('310-G01-000-000-000', '310-G04-000-000-000','310-G04-000-000-001')
);

and to find the value use the MEMBER OF collection operator:

SELECT id
FROM   test_table
WHERE  '310-G01-000-000-000' MEMBER OF column1;

db<>fiddle here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文