代码之家  ›  专栏  ›  技术社区  ›  Kevin Babcock

在Oracle中,如何用varchar2列对索引进行分区?这是个坏主意吗?

  •  1
  • Kevin Babcock  · 技术社区  · 15 年前

    我正在使用Oracle 10g企业版。

    我们的Oracle数据库中的一个表存储另一个文本列的SOUNDEX值表示。我们使用的是自定义Soundex实现,其中Soundex值比传统Soundex算法(如Oracle使用的算法)生成的值长。这真是离题了。

    基本上,我有一个varchar2列,它的值包含一个字符,后跟一个动态数字值(例如“A12345”、“S382771”等)。表是由另一列分区的,但是我想向soundex列添加一个分区索引,因为它经常被搜索。尝试使用soundex列的第一个字符添加范围分区索引时,效果非常好:

    create index IDX_NAMES_SOUNDEX on NAMES_SOUNDEX (soundex)
    global partition by range (soundex) (
        partition IDX_NAMES_SOUNDEX_PART_A values less than ('B'),  -- 'A%'
        partition IDX_NAMES_SOUNDEX_PART_B values less than ('C'),  -- 'B%'
        ...
    );
    

    但是,为了更均匀地分布分区的大小,我想用前两个字符定义一些分区,如下所示:

    create index IDX_NAMES_SOUNDEX on NAMES_SOUNDEX (soundex)
    global partition by range (soundex) (
        partition IDX_NAMES_SOUNDEX_PART_A5 values less than ('A5'), -- 'A0% - A4%'
        partition IDX_NAMES_SOUNDEX_PART_A values less than ('B'),   -- 'A4% - A9%'
        partition IDX_NAMES_SOUNDEX_PART_B values less than ('C'),   -- 'B%'
        ...
    );
    

    我不知道如何使用varchar2列正确地对分区进行范围划分。我相信这是一个不太理想的选择,所以也许有人可以推荐一个更好的解决方案。下面是我表中Soundex数据的分布:

    -----------------------------------
    |  SUBSTR(SOUNDEX,1,1)  |  COUNT  |
    -----------------------------------
    |                    A  | 6476349 |
    |                    B  |  854880 |
    |                    D  |  520676 |
    |                    F  | 1200045 |
    |                    G  |  280647 |
    |                    H  | 3048637 |
    |                    J  |  711031 |
    |                    K  | 1336522 |
    |                    L  |  348743 |
    |                    M  | 3259464 |
    |                    N  | 1510070 |
    |                    Q  |  276769 |
    |                    R  | 1263008 |
    |                    S  | 3396223 |
    |                    V  |  533844 |
    |                    W  |  555007 |
    |                    Y  |  348504 |
    |                    Z  | 1079179 |
    -----------------------------------
    

    如您所见,分布不是均匀分布的,这就是为什么我要使用前两个字符而不是第一个字符定义范围分区。

    建议?

    谢谢!

    3 回复  |  直到 15 年前
        1
  •  3
  •   tuinstoel    15 年前

    你的问题到底是什么?

    您不知道如何将表拆分为n个相等的部分以避免倾斜吗?

    您可以使用分析函数percentile_disc()来实现这一点。

    这里有一个n=100的SQL+示例,我承认它不是很复杂,但它可以完成这项工作。

    set pages 0
    set lines 200
    
    drop table random_strings;
    
    create table random_strings 
    as 
    select upper(dbms_random.string('A', 12)) rndmstr
    from dual 
    connect by level < 1000;
    
    
    spool parts
    
    select 'select '||level||'/100,percentile_disc('||level||
           '/100) within group (order by RNDMSTR) from random_strings;' 
           sql_statement
    from dual 
    connect by level <= 100
    /
    
    spool off
    

    这将在文件parts.lst中输出:

    select 1/100,percentile_disc(1/100) within group (order by RNDMSTR) from random_strings;                                                                                                                
    select 2/100,percentile_disc(2/100) within group (order by RNDMSTR) from random_strings;                                                                                                                
    select 3/100,percentile_disc(3/100) within group (order by RNDMSTR) from random_strings;                                                 
    ...
    select 100/100,percentile_disc(100/100) within group (order by RNDMSTR) from random_strings;                                                 
    

    现在可以运行script parts.lst来获取分区值。每个分区最初将包含1%的数据。

    script parts.lst将输出:

       ,01 AJUDRRSPGMNP
       ,02 AOMJZQPZASQZ
       ,03 AWDQXVGLLUSJ
       ,04 BIEPUHAEMELR
       .... 
       ,99 ZTMHDWTXUJAR
       1   ZYVJLNATVLOY
    
        2
  •  0
  •   Justin Cave    15 年前

    除了soundex值之外,分区键还在搜索表吗?或者只是通过Soundex专栏搜索?

    如果您只是想在分区之间实现数据的均匀分布,您是否考虑过使用哈希分区而不是范围分区?假设您为分区数选择2的幂,这将使分区之间的数据分布相当均匀。

        3
  •  0
  •   Tom Clark AaiCanHelp.com    15 年前

    跟我说话! 你能告诉我为什么要对这个表进行分区吗?听起来像是一个OLTP表,可能不需要是分区。我们不想仅仅说我们是被划分的。告诉我您正试图通过对这个表进行分区来完成什么,我可以帮助您选择一个正确的分区方案。分区不等于更快的查询。在某些情况下,它实际上会导致查询速度变慢。

    我在上面看到了您的一些额外想法,我不认为您需要对表进行分区。如果您的查询要在整个分区上执行聚合,那么您可能需要分区。如果您将拥有数亿行数据,那么您可能需要分区来帮助DBA维护。如果您只想让查询快速运行,那么主键索引就足够了。请告诉我

    只需在所需列上创建一个全局索引。