小编Iva*_*anD的帖子

为 WHERE 和 ORDER BY 创建多列索引

我正在尝试创建一个同时在 WHERE 和 ORDER BY 子句中使用的索引。阅读 Postgres 14 文档(11.4.索引和 ORDER BY - https://www.postgresql.org/docs/14/indexes-ordering.html)让我相信:

除了简单地查找查询要返回的行之外,索引还可以按特定的排序顺序传递它们。这允许遵守查询的 ORDER BY 规范,而无需单独的排序步骤。

哇,听起来棒极了,我们来试试吧!我创建了一个测试表,一个包含 WHERE 和 ORDER BY 列的索引,并用数据填充它:

DROP TABLE IF EXISTS testdata;
CREATE TABLE testdata
(
    question_id   TEXT        NOT NULL UNIQUE PRIMARY KEY,
    answerer_id   TEXT        NOT NULL,
    question_date TIMESTAMPTZ NOT NULL,
    answer_date   TIMESTAMPTZ NOT NULL
);

DROP INDEX IF EXISTS idx1;
CREATE INDEX idx1 ON testdata (answerer_id, answer_date, question_date);

TRUNCATE testdata;
INSERT INTO testdata(question_id, answerer_id, question_date, answer_date)
SELECT CONCAT('question_', LPAD(i::TEXT, 4, '0')),
       CONCAT('answerer_', …
Run Code Online (Sandbox Code Playgroud)

postgresql index execution-plan

6
推荐指数
1
解决办法
1225
查看次数

对于不区分大小写的数据,为什么不使用两列而不是排序规则?

我需要在 Postgres 15 中存储电子邮件(如“ivan@email.com”),能够以不区分大小写的方式搜索它们(“iVaN@email.com”、“IVAN@email.com”等是相同的) ),并能够检索原始电子邮件以将其用于实际发送电子邮件。

处理不区分大小写的数据的建议方法是使用排序规则:

DROP TABLE IF EXISTS test_collation;
DROP COLLATION IF EXISTS case_insensitive;

CREATE COLLATION case_insensitive (PROVIDER = icu, LOCALE = '@colStrength=secondary', DETERMINISTIC = FALSE);

CREATE TABLE test_collation
(
    original_email TEXT COLLATE case_insensitive NOT NULL UNIQUE PRIMARY KEY
);

INSERT INTO test_collation (original_email)
VALUES ('IVAN@email.com');

-- This entry fails as expected as a duplicate:
INSERT INTO test_collation (original_email)
VALUES ('ivAn@email.com');

-- Getting the original email provided by the user regardless of case in which it is entered: …
Run Code Online (Sandbox Code Playgroud)

postgresql index collation postgresql-15

6
推荐指数
3
解决办法
2612
查看次数