在 postgres 9.0 上,将 index_scan 和 seq_scan 都设置为 Off。为什么它将查询性能提高了 2 倍?
这可能有助于某些查询运行得更快,但几乎肯定会使其他查询运行得更慢。 对于诊断目的来说,这是有趣的信息,但对于长期的"解决方案"来说却是一个坏主意。
PostgreSQL 使用基于成本的优化器,它根据通过扫描表(通常通过自动真空)和成本因素收集的统计信息来查看所有可能计划的成本。 如果未选择最快的计划,通常是因为成本计算因素未准确模拟环境的实际成本、统计信息不是最新的,或者统计信息不够细粒度。
打开index_scan
并重新打开seq_scan
后:
-
我通常发现
cpu_tuple_cost
默认值太低;我经常看到通过将其设置为 0.03 而不是默认的 0.01 来选择更好的计划;而且我从未见过覆盖会导致问题。 -
如果数据库的活动部分适合 RAM,请尝试将
seq_page_cost
和random_page_cost
降低到 0.1。 -
请务必将
effective_cache_size
设置为shared_buffers
和操作系统显示为缓存的任何内容的总和。 -
切勿禁用自动吸尘器。 您可能希望调整参数,但要非常小心地执行此操作,并进行少量增量更改和后续监视。
-
您可能需要偶尔运行显式
VACUUM ANALYZE
或ANALYZE
命令,特别是对于临时表或刚刚进行了大量修改并即将在查询中使用的表。 -
你可能想增加
default_statistics_target
、from_collapse_limit
、join_collapse_limit
或一些geqo设置;但是如果没有比你目前给出的更多的细节,很难判断这些是否合适。
您可以尝试在单个连接上设置不同成本系数的查询。 当您确认适合整个混音的配置(即,它可以准确地对环境中的成本进行建模)时,您应该在postgresql.conf
文件中进行更新。
如果您需要更有针对性的帮助,请显示表的结构、查询本身以及为查询运行EXPLAIN ANALYZE
的结果。 对操作系统和硬件的描述以及PostgreSQL配置也有很大帮助。
为什么?
最合乎逻辑的答案是因为数据库表的配置方式。
如果不发布表架构,我只能猜测您的索引没有高基数。
也就是说,如果你的索引包含的信息太多而没有用,那么它的效率就会低得多,或者实际上会变慢。
基数是衡量索引中某一行的唯一性的度量。基数越低,查询速度越慢。
一个完美的例子是索引中有一个布尔字段;也许你的数据库中有一个联系人表,它有一个布尔列,根据客户是否希望第三方联系,记录真或假。
平均而言,如果您确实"从OptIn = true的联系人中选择*";您可以想象您会返回很多联系人;想象一下在我们的例子中50%的联系人。
现在,如果您将此"Optin"列添加到同一表的索引中;按理说,无论其他选择器多么精细,由于"OptIn"的值,您都将始终返回表的 50%。
这是低基数的一个完美示例;它会很慢,因为任何涉及该索引的查询都必须选择表中 50% 的行;然后能够应用进一步的 WHERE 过滤器来再次减少数据集。
长话短说;如果您的索引包含错误字段或仅表示表中的每一列;然后 SQL 引擎必须求助于逐行测试。
无论如何,以上内容在您的情况下是理论上的;但这是查询突然开始花费更长时间的已知常见原因。
请填写有关您的数据结构、索引定义和实际查询的空白,这真的很慢!