【问题标题】:What to index on queries with lots of columns in the WHERE clause在 WHERE 子句中有很多列的查询上索引什么
【发布时间】:2017-02-01 00:43:54
【问题描述】:

为公寓网站构建搜索引擎,但我不知道如何索引 apartments 表。

查询示例:

  • ...WHERE city_id = 1 AND size > 500 AND rooms = 2
  • ...WHERE area_id = 2 AND ad_type = 'agent' AND price BETWEEN 10000 AND 14000
  • ...WHERE area_id = 2 OR area_id = 4 AND published_at > '2016-01-01' AND ad_type = 1

如您所见,列可以变化很大,WHERE 子句中的列数可以多达 10 个,甚至可能更多。

  • 我应该将它们全部编入索引吗?
  • 只有最常见的?

【问题讨论】:

  • 我不建议将所有这些都编入索引,属性列通常不应编入索引(如大小、房间和价格)。所以也许是 (city_id) , (area_id,ad_type) ,但没有看到数据并针对特定的 WHERE ,我们无法告诉你什么是最好的。顺便说一句 - 使用 area_id IN(2,4) 而不是两个 OR

标签: postgresql indexing


【解决方案1】:

您必须弄清楚您将在此查询中使用哪些WHERE 子句、每个子句出现的频率以及每个条件的选择性。

  • 除非必要,否则不要为很少出现的查询编制索引。

  • 使用多列索引,从= 比较中出现的那些列开始。

  • 关于多列索引中列的顺序,从那些将在查询中单独使用的列开始(索引可用于只有部分列的查询,前提是它们位于索引的开头)。

  • 您可以省略选择性较低的列,例如 gender

例如,对于您上面的查询,如果它们都是频繁的并且所有列都是选择性的,那么这些索引会很好:

... ON apartments (city_id, rooms, size)

... ON apartments (area_id, ad_type, price)

... ON apartments (area_id, ad_type, published_at)

这些索引也可用于仅包含 area_idcity_idWHERE 子句。

索引太多是不好的。

如果上述方法会导致索引过多,例如因为用户可以为WHERE 子句选择任意列,所以最好对单个列或偶尔定期组合在一起的列进行索引。

这样 PostgreSQL 可以选择一个位图索引扫描来为一个查询组合多个索引。这比常规索引扫描效率低,但通常比顺序扫描好。

【讨论】:

  • 谢谢,非常有用。不知道多列索引的顺序很重要! :)
【解决方案2】:

Postgres 9.6 提供了一个新的扩展来准确解决您的难题

bloom index

来自将三元组索引或文本搜索带入 Postgres 的同一作者(除其他外)。

所有相关列上的单个bloom索引适用于WHERE子句中它们的任何组合 - 即使不是单独的btree索引每一列。但是与许多索引相比,单个索引要小得多且维护起来更便宜。您必须权衡成本和收益。

bloom 索引适用于 许多 可以以多种方式组合的索引列。

我可能会将作为“包罗万象”的bloom 索引与一些定制的多列btree 索引结合起来,以优化最常见的组合(along the guidelines provided by @Laurenz)和最常查询列上的一些单列索引。

更多解释:

该功能是新功能,存在一些重要限制。引用手册:

  • 该模块仅包含 int4text 的运算符类。

  • 仅支持 = 运算符进行搜索。但是可以添加对具有联合和交集操作的数组的支持 未来。

所以不适用于 published_at,它看起来像 date(但您仍然可以提取 EPOCH 并为其编制索引)并且仅用于相等谓词。

创建扩展后(每个 DB 一次):

CREATE EXTENSION bloom;

创建一个bloom索引:

CREATE INDEX tbl_bloomidx
ON tbl USING bloom (area_id, city_id, size, rooms, ad_type);  -- many more columns?

还有一些其他的:

CREATE INDEX tbl_published_at ON tbl (published_at);
CREATE INDEX tbl_published_at ON tbl (price);
-- some popular combinations...

The manual 有一些比较bloom、多列和单列btree 索引的示例。很有见地。

【讨论】:

    猜你喜欢
    • 2022-01-24
    • 2016-03-19
    • 1970-01-01
    • 2016-06-26
    • 1970-01-01
    • 1970-01-01
    • 2012-12-29
    • 2019-10-03
    相关资源
    最近更新 更多