在 postgres 9.0 上,将 index_scan 和 seq_scan 都设置为 Off。为什么它将查询性能提高了 2 倍?
2 回答
这可能有助于一些查询运行得更快,但几乎肯定会使其他查询变慢。这是用于诊断目的的有趣信息,但对于长期“解决方案”来说是个坏主意。
PostgreSQL 使用基于成本的优化器,它根据通过扫描表(通常通过 autovacuum)收集的统计信息和成本因素来查看所有可能计划的成本。如果它没有选择最快的计划,通常是因为您的成本计算因素没有准确地模拟您的环境的实际成本,统计数据不是最新的,或者统计数据不够细粒度。
开启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
永远不要禁用 autovacuum。您可能想要调整参数,但要非常小心,进行小的增量更改和后续监控。
您可能需要偶尔运行显式
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 引擎不得不求助于逐行测试。
无论如何,以上对于您的情况是理论上的;但这是查询突然开始花费更长的时间的一个已知常见原因。
请填写有关您的数据结构、索引定义和实际查询速度非常慢的空白!