0

PostgreSQL 9.2. Two variations of records can be stored in the following table. alarmConfigurations entries where ac_p_id is NOT NULL can exist more than once, but those where ac_p_id is NULL must only exist once (hence the ac_unique_row_no_port constraint).

As you can see, regular indexes are created on all other foreign keys, these get scanned a lot. But for ac_p_id...

  1. Is there any particular advantage to creating the non-unique constraint ac_index_p_id with IS NOT NULL (as opposed to not specifying, like the others)?
  2. In fact, if I only create ac_unique_row_no_port, will that also be used for scans where ac_p_id is NOT NULL?

Thanks in advance.

CREATE TABLE alarmConfigurations (
  ac_id SERIAL PRIMARY KEY,
  ac_ad_code TEXT NOT NULL,
  ac_ad_et_code TEXT NOT NULL,
  ac_e_id INTEGER NOT NULL,
  ac_as_code TEXT,
  ac_p_id INTEGER,
  ac_details HSTORE,          -- extra configuration
  CONSTRAINT ac_ad_fkey FOREIGN KEY (ac_ad_code, ac_ad_et_code)
    REFERENCES alarmDefinitions (ad_code, ad_et_code)
    ON UPDATE CASCADE ON DELETE CASCADE,
  CONSTRAINT ac_as_code_fkey FOREIGN KEY (ac_as_code)
    REFERENCES alarmSeverities (as_code)
    ON UPDATE CASCADE ON DELETE RESTRICT,
  CONSTRAINT ac_e_id_fkey FOREIGN KEY (ac_e_id)
    REFERENCES entities (e_id) ON DELETE CASCADE,
  CONSTRAINT ac_p_id_fkey FOREIGN KEY (ac_p_id)
    REFERENCES ports (p_id) ON DELETE CASCADE
);
CREATE INDEX ac_index_e_id ON alarmConfigurations(ac_e_id);
CREATE INDEX ac_index_ad_code ON alarmConfigurations(ac_ad_code);
CREATE INDEX ac_index_ad_et_code ON alarmConfigurations(ac_ad_et_code);
CREATE INDEX ac_index_p_id ON alarmConfigurations(ac_p_id)
  WHERE ac_p_id IS NOT NULL;
CREATE UNIQUE INDEX ac_unique_row_no_port
  ON alarmConfigurations(ac_ad_code, ac_ad_et_code, ac_e_id)
  WHERE ac_p_id IS NULL;
4

1 回答 1

1

使用 IS NOT NULL 创建非唯一约束 ac_index_p_id 有什么特别的优势(而不是像其他人一样不指定)?

就个人而言,如果您想使用任意where ac_p_id is null or ac_p_id = ?或其他一些复杂的表达式运行查询,我会将 where 子句放在那个之外。

事实上,如果我只创建 ac_unique_row_no_port,它是否也可用于 ac_p_id 不为 NULL 的扫描?

不,只有ac_p_id is null在您的子句中明确指定时才会使用它。索引中使用的整个where子句必须在查询中才能被考虑。(给予或接受 PG 处理的轻微重写,但不要指望他们未经测试。)

于 2013-09-11T15:12:05.407 回答