优化PostgreSQL多表搜索查询

时间:2015-03-24 10:53:15

标签: performance postgresql search

我的网站上有一个多表搜索工具,用分页显示结果。

PostgreSQL表有几万行,我想提高性能:如果我搜索一个单词(或几个),它需要几秒钟,但如果我搜索一个字母(对于例子" e"),大约需要20秒。

这是一个非常简化的数据库,用于示例目的:

create table DOG
(
    id_dog SERIAL PRIMARY KEY,
    name VARCHAR(100) UNIQUE NOT NULL,
    birth_date TIMESTAMP NULL
);

create table CAT
(
    id_cat SERIAL PRIMARY KEY,
    name VARCHAR(100) UNIQUE NOT NULL,
    birth_date TIMESTAMP NULL
);

create table BIRD
(
    id_bird SERIAL PRIMARY KEY,
    name VARCHAR(100) UNIQUE NOT NULL,
    birth_date TIMESTAMP NULL
);

insert into DOG values (0, 'Rex', '2002-03-05 12:02:06');
insert into DOG values (1, 'Rantanplan', '2002-03-05 12:02:06');
insert into DOG values (2, 'Milou', '2002-03-05 12:02:06');

insert into CAT values (0, 'Grominet', '2002-03-05 12:02:06');
insert into CAT values (1, 'Bella', '2002-03-05 12:02:06');
insert into CAT values (2, 'Molly', '2002-03-05 12:02:06');

insert into BIRD values (0, 'Titi', '2002-03-05 12:02:06');
insert into BIRD values (1, 'Bip-Bip', '2002-03-05 12:02:06');
insert into BIRD values (2, 'Sunny', '2002-03-05 12:02:06');

这是相应的简化请求(在实际情况下,我在更多字段中搜索,表格不相似):

select *, count(*) over() as count 
from 
(
    (
        select id_dog as id, birth_date as date, name as title, varchar(4) 'DOG' as table
        from DOG d 
        where unaccent(lower(array_to_string(array[d.name, to_char(d.birth_date, 'YYYY-MM-DD HH24:MI:SS')], ' ')))
        like '%' || lower(unaccent('a')) || '%' 
    ) 

    union 
    (
        select id_cat as id, birth_date as date, name as title, varchar(4) 'CAT' as table
        from CAT c
        where unaccent(lower(array_to_string(array[c.name, to_char(c.birth_date, 'YYYY-MM-DD HH24:MI:SS')], ' '))) 
        like '%' || lower(unaccent('a')) || '%' 
    ) 
    union 
    (
        select id_bird as id, birth_date as date, name as title, varchar(4) 'BIRD' as table
        from BIRD b
        where unaccent(lower(array_to_string(array[b.name, to_char(b.birth_date, 'YYYY-MM-DD HH24:MI:SS')], ' '))) 
        like '%' || lower(unaccent('a')) || '%' 
    )
) 
as results order by DATE offset 0 limit 10;

有什么想法改善这个吗?也许有左联?

问题似乎是我需要计算结果的数量才能显示我的分页。如果我限制每个子选择中的结果数量,则查询运行速度很快,但我没有得到正确的结果计数。

0 个答案:

没有答案