Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 是否可以暂时禁用Postgres中的索引?_Performance_Debugging_Postgresql_Indexing - Fatal编程技术网

Performance 是否可以暂时禁用Postgres中的索引?

Performance 是否可以暂时禁用Postgres中的索引?,performance,debugging,postgresql,indexing,Performance,Debugging,Postgresql,Indexing,我有一个表上的索引,我想暂时禁用,但我找不到任何文档表明这是可能的 原因:我有一个索引,它可能会导致查询出现问题,而这些问题与它设计用来加速的查询无关。这是一个新的索引,自引入以来,整个系统的速度似乎较慢。我只是希望能够可靠地消除它的罪魁祸首,这似乎是最简单的方法,其他解决方案建议,以及更好的问题建议,也是受欢迎的 begin; drop index foo_ndx; explain analyze select * from foo; rollback; 我不认为有一种方法可以只禁用一个,尽

我有一个表上的索引,我想暂时禁用,但我找不到任何文档表明这是可能的

原因:我有一个索引,它可能会导致查询出现问题,而这些问题与它设计用来加速的查询无关。这是一个新的索引,自引入以来,整个系统的速度似乎较慢。我只是希望能够可靠地消除它的罪魁祸首,这似乎是最简单的方法,其他解决方案建议,以及更好的问题建议,也是受欢迎的

begin;
drop index foo_ndx;
explain analyze select * from foo;
rollback;
我不认为有一种方法可以只禁用一个,尽管您可以在事务中这样做,使从中恢复非常简单。您还可以禁用indexscan以禁用所有索引


另外,请确保您正在对查询执行
解释分析

您可以拨动系统目录以禁用索引:

update pg_index set indisvalid = false where indexrelid = 'test_pkey'::regclass
这意味着索引不会用于查询,但仍将被更新。它是用于并发索引构建的标志之一。请注意,我只做了一个快速测试,看看索引是否仍在更新,请注意清空。

我创建了一个函数,可以在各种情况下执行此操作。你当然需要小心,但它确实有效

CREATE OR REPLACE PROCEDURE global.enable_indexes(
    IN schema_name TEXT
,   IN table_name TEXT
,   IN index_name TEXT
,   IN enable_use BOOLEAN
,   IN enable_updates BOOLEAN
,   IN skip_essentials BOOLEAN DEFAULT TRUE
) AS
$$
DECLARE
    each_record RECORD;
BEGIN

/*
USAGE:

schema_name:
- filters down by schema name
- if NULL then does not filter
table_name:
- filters down by table name (careful - not schema qualified)
- if NULL then does not filter
index_name:
- filters down by index name (careful - not schema qualified)
- if NULL then does not filter
enable_use:
- This SETs the index as being available for use.
- If enable_updates is FALSE, then automatically FALSE
enable_updates:
- This SETs the index to be updated (which doesn't imply that it is enabled for use)
- When this was previously FALSE for the given index, then when setting to true will also trigger a rebuild of the index
skip_essentials:
- When this is true, PRIMARY and UNIQUE indexes will not be included in the scope (no changes).
- Optional
*/


IF array_replace(ARRAY[schema_name, table_name, index_name], NULL, '') <@ ARRAY[''] THEN
    RAISE EXCEPTION 'Error: Must specify at least one of schema_name | table_name | index_name';
END IF;

IF enable_updates IS FALSE THEN
    enable_use := FALSE;
    RAISE INFO 'FYI: Because enable_updates is FALSE, then likewise enable_use must be as well';
END IF;

FOR each_record IN
    select
        indexrelid
    ,   (schemaname||'.'||indexname) as index_name
    ,   indisvalid
    ,   indisready
    ,   (schemaname||'.'||tablename) as table_name
    ,   (CASE WHEN indisready IS FALSE and enable_use IS TRUE AND enable_updates IS TRUE THEN TRUE ELSE FALSE END) as needs_rebuilding
    FROM pg_indexes, pg_index
    WHERE
        indexrelid = (schemaname||'.'||indexname)::regclass
    AND case when schema_name <> '' THEN schemaname = schema_name ELSE TRUE END
    AND case when table_name <> '' THEN tablename = table_name ELSE TRUE END
    AND case when index_name <> '' THEN indexname = index_name ELSE TRUE END
    AND case when true THEN least(indisprimary, indisunique) = FALSE ELSE TRUE END
    AND case when skip_essentials THEN least(indisprimary, indisunique) = FALSE ELSE TRUE END
LOOP
    BEGIN

    RAISE INFO 'Set index % to have use % and updates %.'
        ,   each_record.index_name
        ,   (case when each_record.indisvalid AND enable_use THEN 'enabled (not changed)' WHEN NOT each_record.indisvalid AND enable_use THEN 'enabled (changed)' else 'disabled' END)
        ,   (case when each_record.indisready AND enable_updates THEN 'enabled (not changed)' WHEN NOT each_record.indisready AND enable_updates THEN 'enabled (changed)' else 'disabled' END)
    ;

    UPDATE pg_index
    SET
        indisvalid = enable_use
    ,   indisready = enable_updates
    WHERE
        indexrelid = each_record.indexrelid
    ;

    IF each_record.needs_rebuilding THEN
        RAISE INFO '... Reindexing and Analyzing %', each_record.index_name;
        EXECUTE format('REINDEX INDEX %1$s; ANALYZE %2$s;', each_record.index_name, each_record.table_name);
    END IF;

    COMMIT;

    END;

END LOOP;

END
$$
LANGUAGE plpgsql
;
创建或替换过程global.enable\u索引(
在schema_name文本中
,在表_名称文本中
,在索引名称文本中
,在enable_中使用布尔值
,在“启用\更新布尔值”中
,在skip_essentials中,布尔值默认为TRUE
)作为
$$
声明
每个记录;
开始
/*
用法:
架构名称:
-按架构名称筛选
-如果为NULL,则不进行筛选
表格名称:
-按表名向下筛选(小心-不符合架构)
-如果为NULL,则不进行筛选
索引名称:
-按索引名筛选(小心-不符合架构)
-如果为NULL,则不进行筛选
启用或使用:
-这会将索引设置为可供使用。
-如果enable_updates为FALSE,则自动为FALSE
启用\u更新:
-这将设置要更新的索引(这并不意味着它已启用以供使用)
-如果给定索引先前为FALSE,那么当设置为true时,也将触发索引的重建
跳过基本要素:
-如果这是真的,则主索引和唯一索引将不包括在范围中(无更改)。
-可选的
*/

如果数组替换(数组[schema\u name,table\u name,index\u name],NULL',),谢谢。不幸的是,我的问题是,我不知道哪些查询速度变慢了:我为其安装索引的所有内容都非常快,只是整个系统都崩溃了。因此,我需要在几分钟内全局禁用索引,而不仅仅是在一个事务中禁用。给您一个upvote,因为这是对单个查询执行此操作的正确方法。如果不是因为我的问题的愚蠢的普遍性,你会解决它的。建议使用
解释分析
是开始了解发生了什么的正确方法。然后你可以说,“为什么
索引的存在会导致
索引扫描的时间从X变为Y?”如果你不知道哪些查询比较慢,那么打开长时间运行语句的日志,看看。我已经读到了,这会如何影响其他并发查询?他们会使用或不使用索引,或阻止,直到这个事务完成吗?@ SmiMeMe我想如果你把<代码> IndeStase[/Cord> >设为false,这将禁用更新:你也应该考虑与此相关的限制:对RDS不起作用?代码>错误:关系pg_索引的权限被拒绝