sql - 按名字和姓氏搜索的 Postgresql 查询,我应该创建哪些索引?

标签 sql postgresql performance

我正在使用此查询按“名字和姓氏”或“姓氏和名字”进行搜索:

SELECT
    "id",
    "firstname",
    "lastname"
FROM
    "plyers"
WHERE
  lower( REPLACE ( CONCAT ( lastname, firstname ), ' ', '' ) ) LIKE '%joh%'
  OR
  lower( REPLACE ( CONCAT ( firstname, lastname ), ' ', '' ) ) LIKE '%joh%'
ORDER BY "id" DESC

鉴于此

  1. 我正在使用 Postgresql 13

  2. 用户可以搜索“John Belushi”或“Belushi John”或“lushi”或“lushi乔

  3. 搜索文本(在本例中为 joh)始终是 lowered() 并清除每个空格:每个单词之前、期间和之后。例如。如果我写“ lushi JO ”,最终的搜索文本是:“lushijo

  4. 此查询经常用于搜索列表中的玩家以及自动完成某些选择

问题

  1. 您认为这是一个很好的查询吗?

  2. 你认为有什么方法可以避免 CONCAT(lastname,firstname)CONCAT(firstname,lastname) 吗?

  3. 我应该创建什么索引?我读到这个:https://stackoverflow.com/a/2709967/10088259但我不太明白如何使用它。

最佳答案

使用generated columns , 并在上面加上索引。

ALTER TABLE test
    ADD COLUMN first_last text GENERATED ALWAYS AS (lower(REPLACE(first || last, ' ', ''))) STORED;

CREATE INDEX IF NOT EXISTS players_first_last_idx ON test USING gin (first_last gin_trgm_ops);

ALTER TABLE test
    ADD COLUMN last_first text GENERATED ALWAYS AS (lower(REPLACE(last || first, ' ', ''))) STORED;

CREATE INDEX IF NOT EXISTS players_first_last_idx ON test USING gin (last_first gin_trgm_ops);

现在 WHERE 子句将能够使用索引:

SELECT
    "id",
    "firstname",
    "lastname"
FROM
    "plyers"
WHERE
  first_last LIKE '%joh%'
  OR
  last_first LIKE '%joh%'
ORDER BY "id" DESC

LIKE 查询创建索引的很好的解释:https://niallburkley.com/blog/index-columns-for-like-in-postgres/

关于sql - 按名字和姓氏搜索的 Postgresql 查询,我应该创建哪些索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64295130/

相关文章:

sql - 当我运行 left join 时,内部发生了什么?

php - MySQL 多表或少表

python - 与 anydbm 相比,带有 Python 的 sqlite 慢得不合理

django - 每天在特定时间清除表中的数据

PHP:如何删除/替换特定的 href 属性值

SQL SELECT FROM ... AS 与数据类型说明符?

MySQL 选择不同但仅当所有第二列 = 1 时?

mysql - 连接多个表的语法

sql - 如何通过 Rails 迁移设置 Postgres 中主键 (ID) 列的起点

postgresql - 在 AWS ec2 实例上通过 sqlalchemy to_sql 过程插入;面临位数据类型列的问题