创建表哈希以提升性能

来自 PostgreSQL wiki
跳转到导航跳转到搜索

创建表哈希以提升性能

文章仍在审核和调试过程中。

本文采用一种非常规技术实现查询性能提升,即将我们表中的文本字段创建为哈希。这适用于精确搜索,如果要查找字词,那么需要稍微了解更多有关 TSearch(包含在 Pgsql84 中)的信息。


使用 CRC32

创建一个名为 crc.c 的文件,并在该文件中保存以下代码

/*
 * CYCLIC REDUNDANCY CHECK
 */

#include "postgres.h"
#include "fmgr.h"

#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif

PG_FUNCTION_INFO_V1(pg_crc_simple);


Datum 
pg_crc_simple(PG_FUNCTION_ARGS){

        char *message = PG_GETARG_TEXT_P(0);
        //size_t argumentlen = VARSIZE(message)-VARHDRSZ;

        int i, j;
        unsigned int byte, crc, mask;
        int32  normalize;
        static unsigned int table[256];
        /* Seteamos la tabla de ser necesario. */
        if (table[1] == 0) {
                for (byte = 0; byte <= 255; byte++) {
                        crc = byte;
                        for (j = 7; j >= 0; j--) { // 8veces
                                mask = -(crc & 1);
                                crc = (crc >> 1) ^ (0xEDB88320 & mask);
                        }
                        table[byte] = crc;
                }
        }

        /* tenemos la tabla y calculamos*/
        i = 0;
        crc = 0xFFFFFFFF;
        while (message[i] != 0) {
                byte = message[i]; // Get next byte.
                crc = (crc >> 8) ^ table[(crc ^ byte) & 0xFF];
                i = i + 1;
        }
        
        normalize = -(~crc);
        PG_RETURN_INT32(normalize);
}


然后,以共享对象的形式将其编译

gcc -I $DIRECTORIO_POSTGRES/include/server/ --shared crc.c

然后,我们必须在引擎中包含该函数

CREATE OR REPLACE FUNCTION pg_crc_simple(text) RETURNS integer
     AS '/usr/local/pgsql84/a.out', 'pg_crc_simple'
     LANGUAGE C STRICT;

请注意,我在 /usr/local/pgsql84 文件夹中编译代码,而默认情况下,“gcc”将输出文件命名为 a.out

试着看看它的效果吧!

postgres=# select pg_crc_simple(random()::text);
 pg_crc_simple_2 
-----------------
      1107002784
(1 row)

在表上的应用

我们假设您有一个包含要 哈希 的字段和存放该值的字段的表。

create table miTablita(nombre text,nombreCrc int);

现在,我输入名称,然后输入其 CRC

insert into miTablita(nombre) (select substring(random()::text,3,9) from generate_series(1,100) );
update miTablita set nombreCrc = pg_crc_simple_2(nombre);