如果您对PostgreSQL可以索引数组列吗?感兴趣,那么本文将是一篇不错的选择,我们将为您详在本文中,您将会了解到关于PostgreSQL可以索引数组列吗?的详细内容,并且为您提供关于centos7
如果您对PostgreSQL 可以索引数组列吗?感兴趣,那么本文将是一篇不错的选择,我们将为您详在本文中,您将会了解到关于PostgreSQL 可以索引数组列吗?的详细内容,并且为您提供关于centos 7下源码编译安装php支持PostgreSQL postgresql手册 postgresql官网下载 postgresql视频教、PostgreSQL hstore数组列的索引、postgresql – postgres 9.6索引只扫描功能索引逻辑上可能但不执行、postgresql – postgres COALESCE懒惰吗?的有价值信息。
本文目录一览:- PostgreSQL 可以索引数组列吗?
- centos 7下源码编译安装php支持PostgreSQL postgresql手册 postgresql官网下载 postgresql视频教
- PostgreSQL hstore数组列的索引
- postgresql – postgres 9.6索引只扫描功能索引逻辑上可能但不执行
- postgresql – postgres COALESCE懒惰吗?
PostgreSQL 可以索引数组列吗?
我在文档中找不到这个问题的明确答案。如果列是数组类型,所有输入的值都会单独索引吗?
我创建了一个包含一int[]
列的简单表,并在其上放置了唯一索引。我注意到我无法添加相同的整数数组,这让我相信索引是数组项的组合,而不是每个项的索引。
INSERT INTO "Test"."Test" VALUES (''{10, 15, 20}'');INSERT INTO "Test"."Test" VALUES (''{10, 20, 30}'');SELECT * FROM "Test"."Test" WHERE 20 = ANY ("Column1");
索引是否有助于此查询?
答案1
小编典典是的,您可以索引一个数组,但您必须使用数组运算符和GIN-index
类型。
例子:
CREATE TABLE "Test"("Column1" int[]); INSERT INTO "Test" VALUES (''{10, 15, 20}''); INSERT INTO "Test" VALUES (''{10, 20, 30}''); CREATE INDEX idx_test on "Test" USING GIN ("Column1"); -- To enforce index usage because we have only 2 records for this test... SET enable_seqscan TO off; EXPLAIN ANALYZE SELECT * FROM "Test" WHERE "Column1" @> ARRAY[20];
结果:
Bitmap Heap Scan on "Test" (cost=4.26..8.27 rows=1 width=32) (actual time=0.014..0.015 rows=2 loops=1) Recheck Cond: ("Column1" @> ''{20}''::integer[]) -> Bitmap Index Scan on idx_test (cost=0.00..4.26 rows=1 width=0) (actual time=0.009..0.009 rows=2 loops=1) Index Cond: ("Column1" @> ''{20}''::integer[])Total runtime: 0.062 ms
笔记
似乎在许多情况下需要 gin__int_ops 选项
create index <index_name> on <table_name> using GIN (<column> gin__int_ops)
我还没有看到没有 gin__int_ops 选项的情况下它可以与 && 和 @> 运算符一起使用
centos 7下源码编译安装php支持PostgreSQL postgresql手册 postgresql官网下载 postgresql视频教
1. 下载源码
$ mkdir /usr/downloads $ wget -c http://cn2.php.net/distributions/php-5.6.20.tar.gz $ tar -xvf php-5.6.20.tar.gz $ mv php-5.6.20 /usr/local/src $ cd !$ & cd php-5.6.20
2. 阅读安装指导
$ ls -also $ less README $ less INSTALL
3. 安装依赖包
$ yum install apr apr-util apr-devel apr-util-devel prce lynx
4. 安装httpd
$ wget -c http://apache.fayea.com//httpd/httpd-2.4.20.tar.gz $ tar -xvf httpd-2.4.20.tar.gz $ cd httpd-2.4.20 $ ./configure \ --prefix=/usr/local/programs/apache2 \ --enable-rewrite \ --enable-so \ --enable-headers \ --enable-expires \ --with-mpm=worker \ --enable-modules=most \ --enable-deflate \ --enable-module=shared $ make $ make install $ cd /usr/local/programs/apache2 $ cp bin/apachectl /etc/init.d/httpd ## 复制启动脚本 $ /etc/init.d/httpd start ## 启动apache服务器,访问http://localhost/ $ egrep -v ''^[ ]*#|^$'' /usr/local/apache2/conf/httpd.conf | nl ## 查看apache服务器的配置 ## 将apache加入系统服务 vi /etc/rc.d/rc.local ``` /usr/local/programs/apache2/bin/apachectl start ``` $ cat /etc/rc.local
4. 安装postgresql
立即学习“PHP免费学习笔记(深入)”;
$ yum install readline-devel ## 安装readline依赖 $ cd /usr/downloads $ wget -c https://ftp.postgresql.org/pub/source/v9.5.0/postgresql-9.5.0.tar.bz2 $ tar -xvf postgresql-9.5.0.tar.bz2 $ cd postgresql-9.5.0 $ ./configure --prefix=/usr/local/programs/postgresql $ make $ su $ make install $ /sbin/ldconfig /usr/local/programs/postgresql/lib ## 刷新下共享动态库 $ cd /usr/local/programs/postgresql $ bin/psql --version ## 检查运行情况 ## 开始对postgresql的配置 $ vi /etc/profile.d/postgresql.sh ## 增加环境变量,不推荐直接在/etc/profile中添加,系统更新升级时会需要merge ``` PATH=/usr/local/programs/postgresql:$PATH export PATH ``` $ source /etc/profile ## 更新环境变量 ## 增加用户和其他文件夹 $ adduser postgres $ passwd postgres $ mkdir /usr/local/programs/postgresql/logs $ mkdir /usr/local/programs/postgresql/data $ chown postgres /usr/local/programs/postgresql/data $ su - postgres ## 初始化数据库 $ ./bin/initdb -D ./data $ ./bin/createdb test $ ./bin/psql test ## 已有数据库,可导入data文件夹后尝试root访问,假如带密码,可能需要进一步研究下 $ ./bin/postgres -D ./data >./logs/start-log-1.log 2>&1 & $ ./bin/psql --list ##列出数据库 ## ok,安装完成 ## 自定义设置,权限控制等,可以跳过,等熟悉使用后再做 ## 编辑数据库配置及权限文件: $ vi /usr/local/programs/postgresql/data/postgresql.conf ## 数据库配置文件 $ chown postgres postgresql.conf $ chmod 644 postgresql.conf $ vi /usr/local/programs/postgresql/data/pg_hba.conf ## 权限文件 $ vi /usr/local/programs/postgresql/data/pg_ident.conf ## 设置开机自启动: $ vi /etc/rc.d/rc.local ## 添加如下内容 ``` /usr/local/programs/postgresql/bin/postgresql start ```
5. 安装php
## 源码已经在第一步中下载,现在开始安装: $ yum install libxml2 libxml2-devel libpng libpng-devel libjpeg libjpeg-devel freetype freetype-devel $ ./configure \ --prefix=/usr/local/programs/php \ --with-apxs2=/usr/local/programs/apache2/bin/apxs \ --with-zlib \ --with-gd \ --with-jpeg-dir \ --with-png-dir \ --with-freetype-dir \ --with-zlib-dir \ --enable-mbstring \ --with-pgsql=/usr/local/programs/postgresql \ --with-pdo-pgsql=/usr/local/programs/postgresql $ make $ make test > Bug #42718 (unsafe_raw filter not applied when configured as default filter) [ext/filter/tests/bug42718.phpt] XFAIL REASON: FILTER_UNSAFE_RAW not applied when configured as default filter, even with flags > Bug #67296 (filter_input doesn''t validate variables) [ext/filter/tests/bug49184.phpt] XFAIL REASON: See Bug #49184 > Bug #53640 (XBM images require width to be multiple of 8) [ext/gd/tests/bug53640.phpt] XFAIL REASON: Padding is not implemented yet > zend multibyte (7) [ext/mbstring/tests/zend_multibyte-07.phpt] XFAIL REASON: https://bugs.php.net/bug.php?id=66582 > zend multibyte (9) [ext/mbstring/tests/zend_multibyte-09.phpt] XFAIL REASON: https://bugs.php.net/bug.php?id=66582 >Bug #70470 (Built-in server truncates headers spanning over TCP packets) [sapi/cli/tests/bug70470.phpt] XFAIL REASON: bug is not fixed yet ## 查阅官方的bug,发现: > id=66582: status : Closed. Fixed in master (PHP7) > id=42718: status : Assigned > id=42718: reference to id=49184, unsolved for many years ## 那就不关心了,直接装吧 $ make install > You may want to add: /usr/local/programs/php/lib/php to your php.ini include_path ## 那就按它说的设置吧 $ cp php.ini-development /usr/local/programs/php/lib/php.ini ``` include_path = ".;/usr/local/programs/php/lib/php" ## 然后,编辑httpd的设置,确保其能正确解析php文件 ``` ... LoadModule php5_module modules/libphp5.so ... AddType application/x-httpd-php .php AddType application/x-httpd-php-source .php5 ... <ifmodule dir_module> DirectoryIndex index.html index.php </ifmodule> ``` ## 重启httpd,测试 $ cd /usr/local/programs/apache2 $ bin/httpd -h $ bin/httpd -k stop $ bin/httpd -f conf/httpd.conf ## 默认设置的www页面在./htdocs/下,那就先去里面建一个测试页面吧 $ vi htdocs/index.php ``` <?php phpinfo(); ?> ``` $ curl http://localhost/index.php |grep postgresql #ok
后续应该做的事
* 1. 启动时,不需要要手动指定配置文件
* 2. php初始化www目录设置
* 3. php 用户、权限管理等
以上就介绍了centos 7下源码编译安装php支持PostgreSQL,包括了postgresql,centos 7方面的内容,希望对PHP教程有兴趣的朋友有所帮助。
PostgreSQL hstore数组列的索引
我知道你也可以在数组列上创建一个GIN索引.
但是在hstore数组上创建索引的语法是什么?
例如
CREATE TABLE customer ( pk serial PRIMARY KEY,customer hstore,customer_purchases hstore[] );
假设客户购买hstore可能是哈希
productId -> 1 price -> 9.99
我在customer_purchases hstore []中有一组数组
我想在customer.customer_purchases [] – >上创建一个索引.的productId
这可能吗?我尝试过不同的CREATE INDEX语法组合,但它们似乎都不支持hstore数组中的索引字段.
相反,创建一个额外的表:
CREATE TABLE customer ( pk bigserial PRIMARY KEY,customer hstore ); CREATE TABLE purchases ( pk bigserial PRIMARY KEY,customer_pk bigint not null,purchase hstore not null,constraint "must be a valid customer!" foreign key (customer_pk) references customer(pk) );
另外,你为什么在这里使用HSTORE?
如果您必须在此处根据“购买”HSTORE创建INDEX,请执行以下操作:
CREATE OR REPLACE FUNCTION purchase_amount(purchase hstore) returns float as $$ select ($1 -> 'price')::float; $$language 'sql' IMMUTABLE; CREATE INDEX "purchases by price" ON purchases (purchase_amount(purchase));
这只是一个理解HSTORE类型的练习吗?或者你是否有一些真正的用例会使你对真实数据的所有混淆都值得?
postgresql – postgres 9.6索引只扫描功能索引逻辑上可能但不执行
我现在有一个查询:
SELECT(xpath('/document/uuid/text()',xmldata))[1]::text,(xpath('/document/title/text()',xmldata))[1]::text FROM xmltable WHERE(xpath('/document/uuid/text()',xmldata))[1]::text = 'some-uuid-xxxx-xxxx'
和索引:
CREATE INDEX idx_covering_index on xmltable using btree ( ((xpath('/document/uuid/text()',xmldata))[1]::text),((xpath('/document/title/text()',xmldata))[1]::text) )
这个索引是逻辑地查看覆盖索引,并应该启用仅索引扫描,因为所有查询的值都包含在索引(uuid和title)中
我现在知道,如果函数调用中使用的列也包含在内,那么Postgres只会识别函数索引的覆盖索引
例如.:
SELECT to_upper(column1) from table where id >10
1)不能被这个索引所涵盖:
CREATE INDEX idx_covering_index on xmltable using btree (id,to_upper(column1));
2)但可以被这个覆盖:
CREATE INDEX idx_covering_index on xmltable using btree (column1,id,to_upper(column1));
从而导致仅索引扫描.
如果我现在尝试使用我的xml设置:
CREATE INDEX idx_covering_index on xmltable using btree (xmldata,((xpath('/document/uuid/text()',xmldata))[1]::text) )
我收到一个错误:
data type xml has no default operator class for access method “btree”
不幸的是,通常使用的“text_ops”或“text_pattern_ops”不接受“xml”作为输入 – 从而渲染我的索引 – 虽然它将覆盖所有值 – 无法支持仅索引扫描.
这可以以提供仅索引扫描的可能性来处理吗?
@ EDIT1:
我知道postgres不能使用1)中的索引作为覆盖索引,但可以使用索引,如2)
我也尝试用非常简单的表来验证这个行为,我也记得要读这个 – 但是我不能忘记我的生活.
create table test ( id serial primary key,quote text ) insert into test (number,quote) values ('I do not kNow any cLever quotes'); insert into test (number,quote) values ('I am sorry'); CREATE INDEX idx_test_functional on test using btree ((regexp_replace(quote,'^I ','BillDoor '))); set enable_seqscan = off; analyze test; explain select quote from test where regexp_replace(quote,'BillDoor ') = 'BillDoor do not kNow any cLever quotes' --> "Index Scan using idx_test_functional on test (cost=0.13..8.15 rows=1 width=27)" drop index idx_test_functional; CREATE INDEX idx_test_functional on test using btree (quote,(regexp_replace(quote,'BillDoor '))); analyze test; explain select quote from test where regexp_replace(quote,'BillDoor ') = 'BillDoor do not kNow any cLever quotes' --> "Index Only Scan using idx_test_functional on test (cost=0.13..12.17 rows=1 width=27)"
@ EDIT2:
xmltable的全表定义:
id serial primary key (clustered),xmldata xml (only data used to filter queries) history xml (never queried or read,just kept in case of legal inquiry) fileinfo text (seldom quieried,sometimes retrieved) "timestamp" timestamp (mainly for legal inquiries too)
该表包含大约:500.000条记录,xmldata的大小在350到800字节之间,历史要大得多,但很少被检索,从未在过滤器中使用
为了记录,确保得到真正的结果,我总是在创建或删除索引后分析xmltable
查询的完整执行计划:
explain analyze select (xpath('/document/uuid/text()',d.xmldata))[1]::text as uuid from xmltable as d where (xpath('/document/uuid/text()',d.xmldata))[1]::text = 'some-uuid-xxxx-xxxx' and (xpath('/document/genre/text()',d.xmldata))[1]::text = 'bio'
被这些印度所覆盖:
create index idx_genre on xmltable using btree (((xpath('/document/genre/text()',xmldata))[1]::text)); create index idx_uuid on xmltable using btree (((xpath('/document/uuid/text()',xmldata))[1]::text)); create index idx_uuid_genre on xmltable using btree (((xpath('/document/uuid/text()',((xpath('/document/genre/text()',xmldata))[1]::text));
首先导致:
"Index Scan using idx_genre on xmldata d (cost=0.42..6303.05 rows=18154 width=32)" " Index Cond: (((xpath('/document/genre/text()'::text,xmldata,'{}'::text[]))[1])::text = 'bio'::text)" " Filter: (((xpath('/document/uuid/text()'::text,'{}'::text[]))[1])::text = 'some-uuid-xxxx-xxxx'::text)"
公平的我以为,只是为了测试我会强迫它使用 – 在我的脑海 – 覆盖索引:
drop index idx_uuid; drop index idx_genre;
现在我得到:
"Bitmap Heap Scan on xmltable d (cost=551.13..16025.51 rows=18216 width=32)" " Recheck Cond: ((((xpath('/document/genre/text()'::text,'{}'::text[]))[1])::text = 'bio'::text) AND (((xpath('/document/uuid/text()'::text,'{}'::text[]))[1])::text = 'some-uuid-xxxx-xxxx'::text))" " -> Bitmap Index Scan on idx_uuid_genre (cost=0.00..546.58 rows=18216 width=0)" " Index Cond: ((((xpath('/document/genre/text()'::text,'{}'::text[]))[1])::text = 'some-uuid-xxxx-xxxx'::text))"
我也尝试在索引中切换uuid和类型的位置,同样的执行计划.
根据文档:postgresql可以在索引类型支持时进行索引扫描(即,btree始终支持这一点,GiST和SpGiST仅适用于某些特定的操作符,而GIN根本不起作用).并且可以从索引重建原始的索引值.
第二个要求是最有趣的.
在列的情况下,它是简单的(a,b),您的索引能够重建原始的存储值.
并且在功能索引工作的功能的情况下,您应该创建具有原始值的索引.这意味着(f1(a),f2(b))索引将再次出现,因为您无法从这些值重建索引数据(a,b).开发人员提出的解决方法是创建索引(f1(a),f2(b),a,b)在这种情况下,查询计划者能够确定可以运行仅索引扫描,因为索引包含原始数据.
并回到你的问题,创建索引只扫描xml列是不可能的:没有运算符支持xml数据比较关键的btree. xml数据的比较运算符没有定义.因此您不能在任何类型的索引中使用此列,但是您需要在仅索引扫描中提示查询优化器才能执行仅索引扫描.
编辑:(解决方案如何在特定的xpath表达式上实现仅索引扫描)
如果您知道这些数据将被频繁使用,我建议您通过触发功能解决此问题,并创建2个以上的字段并通过索引来覆盖.这样的事情
ALTER TABLE public.xmltable ADD COLUMN xpath_uuid character varying(36); ALTER TABLE public.xmltable ADD COLUMN xpath_title character varying(100); CREATE INDEX idx_covering_materialized_xml_data ON public.xmltable USING btree (xpath_uuid COLLATE pg_catalog."default",xpath_title COLLATE pg_catalog."default"); CREATE OR REPLACE FUNCTION public.introduce_xml_materialization() RETURNS trigger AS $BODY$BEGIN NEW.xpath_uuid = (xpath('/document/uuid/text()',NEW.xmldata))[1]::text; NEW.xpath_title = (xpath('/document/title/text()',NEW.xmldata))[1]::text; RETURN NEW; END;$BODY$ LANGUAGE plpgsql STABLE COST 100; CREATE TRIGGER index_xml_data BEFORE INSERT OR UPDATE ON public.xmltable FOR EACH ROW EXECUTE PROCEDURE public.introduce_xml_materialization();
然后你可以简单地做:
SELECT xpath_uuid,xpath_title FROM public.xmltable where xpath_uuid = ' uuid1 '
这将显示您仅索引扫描:
"Index Only Scan using idx_covering_materialized_xml_data on xmltable (cost=0.14..8.16 rows=1 width=308)" " Index Cond: (xpath_uuid = ' uuid1 '::text)"
假设数据读取多于写入,这种方法将是最佳的.从插入或更新的成本,它通常与在xpath表达式上创建功能索引相同.
ORIGINAL RESPONSE:(对于愿意调整查询优化器的用户来说,可能很有意思)
那么问题是你的查询优化器认为xPath函数调用是最简单的.即它就像调用简单的数学运算符并且其成本是1.在这种情况下,查询优化器认为,从表中获取并再次计算更容易,然后进行纯索引扫描.
如果增加xpath调用成本,让我们说1000查询优化器会看到这样的调用显着更难(实际上是真的),并且将尝试执行仅索引扫描.在我的测试设置中,我已经执行了
update pg_proc set procost=1 where proname='xpath';
执行计划是
"Bitmap Heap Scan on xmltable (cost=4.17..11.30 rows=3 width=64)" " Recheck Cond: (((xpath('/document/uuid/text()'::text,'{}'::text[]))[1])::text = 'some-uuid-xxxx-xxxx'::text)" " -> Bitmap Index Scan on idx_covering_index_3 (cost=0.00..4.17 rows=3 width=0)" " Index Cond: (((xpath('/document/uuid/text()'::text,'{}'::text[]))[1])::text = 'some-uuid-xxxx-xxxx'::text)"
但是当我做的时候
update pg_proc set procost=1000 where proname='xpath';
执行计划正在切换到仅索引扫描
"Index Scan using idx_covering_index_3 on xmltable (cost=0.15..31.20 rows=3 width=64)" " Index Cond: (((xpath('/document/uuid/text()'::text,'{}'::text[]))[1])::text = 'some-uuid-xxxx-xxxx'::text)"
在我的卷(即没有数据)上,仅索引查询的最小成本显着小于原始索引表扫描中的最大成本,最大成本更大.因此,为了在查询优化上作弊,可能需要在xpath调用成本上放置更高的值.
希望这将有所帮助,出于好奇,只是向我们展示了使用仅索引查询的好处.
postgresql – postgres COALESCE懒惰吗?
SELECT COALESCE( (SELECT value FROM precomputed WHERE ...),alwaysComputeValue(...) );
第二个表达式会被评估吗?
这还取决于执行计划员还是独立的?
Like a CASE expression,COALESCE only evaluates the arguments that are needed to determine the result; that is,arguments to the right of the first non-null argument are not evaluated.
https://www.postgresql.org/docs/9.6/static/functions-conditional.html
但是,如果右边的表达式不是volatile,那么它是否是懒惰的应该没有区别,所以在这种情况下,如果查询计划程序稳定或者是正常的,那么它将是允许的.不可变的,如果这似乎是一个明智的优化.
一个明显的例子是,使用SELECT COALESCE(a,b)FROM表,它可能会检索所有行的a和b字段,而不是检索a然后在必要时检索b.
关于在这里产生任何可观察效果的唯一方法是,如果你编写了一个易失性函数,并故意将其错误标记为稳定或不可变.然后,如果在左侧不为空的合并的右侧,则可以对其进行评估. (当然,一个功能确实很稳定,但如果它稳定,它就没有副作用,如果没有副作用,它是否发生是不可观察的).
鉴于:
CREATE OR REPLACE FUNCTION immutable_func(arg integer) RETURNS integer AS $BODY$ BEGIN RAISE NOTICE 'Immutable function called with %',arg; RETURN arg; END; $BODY$LANGUAGE plpgsql IMMUTABLE; WITH data AS ( SELECT 10 AS num UNION ALL SELECT 5 UNION ALL SELECT 20 ) select coalesce(num,immutable_func(2)) from data
规划器知道它对每行都有相同的immutable_func(2)结果,并为整个查询调用一次,给我们用2调用的消息Immutable函数.所以它确实已被评估,即使它不是在“第一个非空参数的权利的参数未被评估”的规则内.回报是在多个零数的(合理预期)情况下,它仍然只运行一次.
这是违反记录行为的信件是好的,因为我们已经告诉它这样的优化是有效的.如果这导致了问题,那么错误就是将功能标记为IMMUTABLE,而不是在急切的评估中.
它也可以是部分方式.使用SELECT COALESCE(a,Some_Func(b))FROM表,它不会急切地评估Some_Func(b),但它将检索b以便能够这样做.
任何时候它实际上影响(非作弊)可观察行为,遵循规则.
我们今天的关于PostgreSQL 可以索引数组列吗?的分享就到这里,谢谢您的阅读,如果想了解更多关于centos 7下源码编译安装php支持PostgreSQL postgresql手册 postgresql官网下载 postgresql视频教、PostgreSQL hstore数组列的索引、postgresql – postgres 9.6索引只扫描功能索引逻辑上可能但不执行、postgresql – postgres COALESCE懒惰吗?的相关信息,可以在本站进行搜索。
本文标签: