如何优化这些Postgres查询和数据库性能?

时间:2015-02-16 12:26:35

标签: performance postgresql indexing database-performance

我需要一些帮助来优化以下两个几乎相似的查询,但数据选择有点不同。这是我的表定义

CREATE TABLE public.rates (
  rate_id          bigserial NOT NULL PRIMARY KEY,
  prefix           varchar(50),
  rate_name        varchar(30),
  rate             numeric(8,6),
  intrastate_cost  numeric(8,6),
  interstate_cost  numeric(8,6),
  status           char(3) DEFAULT 'act'::bpchar,
  min_duration     integer,
  call_increment   integer,
  connection_cost  numeric(8,6),
  rate_type        varchar(3) DEFAULT 'lcr'::character varying,
  owner_type       varchar(10),
  start_date       timestamp WITHOUT TIME ZONE,
  end_date         timestamp WITHOUT TIME ZONE,
  rev              integer,
  ratecard_id      integer,
  /* Keys */
  CONSTRAINT rates_pkey
    PRIMARY KEY (id)
) WITH (
    OIDS = FALSE
  );

和我正在使用的两个查询,

SELECT
    rates.* ,
    rc.ratecard_prefix ,
    rc.default_lrn ,
    rc.lrn_lookup_method ,
    customers.customer_id ,
    customers.balance ,
    customers.channels AS customer_channels ,
    customers.cps      AS customer_cps ,
    customers.balance  AS customer_balance 
FROM
    rates 
        JOIN ratecards rc 
        ON rc.card_type = 'customer' AND
        rc.ratecard_id = rates.ratecard_id 
        JOIN customers 
        ON rc.customer_id = customers.customer_id 
WHERE
    customers.status = 'act' AND
    rc.status = 'act' AND
    rc.customer_id = 'AB8KA191' AND
    owner_type = 'customer' AND
    '17606109973' LIKE concat (rc.ratecard_prefix, rates.prefix, '%') AND
    rates.status = 'act' AND
    now() BETWEEN rates. start_date AND
    rates.end_date AND
    customers.balance > 0 
ORDER BY
    LENGTH(PREFIX) DESC LIMIT 1;

和第二个,

SELECT
    * 
FROM
    rates 
        JOIN ratecards rc 
        ON rc.card_type = 'carrier' AND
        rc.ratecard_id = rates.ratecard_id 
        JOIN carriers 
        ON rc.carrier_id = carriers.carrier_id 
        JOIN carrier_switches cswitch 
        ON carriers.carrier_id = cswitch.carrier_id 
WHERE
    rates.intrastate_cost < 0.011648 AND
    owner_type = 'carrier' AND
    '16093960411' LIKE concat (rates.prefix, '%') AND
    rates.status = 'act' AND
    carriers.status = 'act' AND
    now() BETWEEN rates.start_date AND
    rates.end_date AND
    rates.intrastate_cost <> -1 AND
    cswitch.enabled = 't' AND
    rates.rate_type = 'lrn' AND
    rates.min_duration >= 6 
ORDER BY
    rates.intrastate_cost ASC,
    LENGTH(rates.prefix) DESC,
    cswitch.priority DESC

我在字段owner_type上创建了一个索引(上面的架构中没有显示),但查询性能并不是预期的。数据库服务器的CPU使用率过高,一切都开始变慢。第一个查询的解释输出为here,第二个问题为here。 当表中的记录数量较少时,事情就会很好,当然,但是当记录数量增加时,CPU会更高。我目前在表中有大约341821条记录。

如何改进查询执行或可能更改查询以加快速度?

我设置了enable_bitmapscan = off因为我觉得这给了我更好的表现。如果设置为on,则每个索引扫描都会跟进Bitmap堆扫描。

通过将查询更改为

,事情确实有所缓解
SELECT
    rates.*,
    rc.ratecard_prefix,
    rc.default_lrn,
    rc.lrn_lookup_method,
    customers.customer_id,
    customers.balance,
    customers.channels AS customer_channels,
    customers.cps      AS customer_cps,
    customers.balance  AS customer_balance 
FROM
    rates 
        JOIN ratecards rc 
        ON rc.card_type = 'customer' AND
        rc.ratecard_id = rates.ratecard_id 
        JOIN customers 
        ON rc.customer_id = customers.customer_id 
WHERE
    customers.status = 'act' AND
    rc.status = 'act' AND
    rc.customer_id = 'AB8KA191' AND
    owner_type = 'customer' AND
    (CONCAT (rc.ratecard_prefix, rates.prefix) IN ('16026813306',
    '1602681330',
    '160268133',
    '16026813',
    '1602681',
    '160268',
    '16026',
    '1602',
    '160',
    '16',
    '1')) AND
    rates.status = 'act' AND
    now() BETWEEN rates.start_date AND
    rates.end_date AND
    customers.balance > 0 
ORDER BY
    LENGTH(PREFIX) DESC LIMIT 1

Postgres.conf是here

但是每个Postgres进程仍需要大约25%+ CPU。我现在也使用pgbouncer来利用连接池,但仍然没有帮助。

0 个答案:

没有答案