索引的作用:帮你快速的查询数据
索引的缺点:
所以说有些东西可以设置为索引,有些东西不推荐设置为索引。
索引引擎参与与查询执行,会根据优化阶段创建的计划器调用它
对于每个索引方法都有如下的扫描技术:
下面为顺序和b-tree索引扫描的简单过程:

索引是一种分离的数据结构,例如 B-Tree,它以额外的写入和存储为代价来加速表上的数据检索以维护它
CREATE INDEX index_name ON table_name [USING method]
(
column_name [ASC | DESC] [NULLS {FIRST | LAST }],
...
);
btree、hash、gist、spgist、gin、 brin(PostgreSQL默认使用btree)ASC指定DESC排序顺序。ASC 是默认值。NULLS FIRST或NULLS LAST指定空值在非空值之前或之后排序。指定NULLS FIRST时为默认值,未指定时为默认值。DESC``NULLS LAST``DESCEXPLAIN语句,来查看此次查询是否属于索引SELECT * FROM address
WHERE phone = '223664661973';

检查是否使用索引:
EXPLAIN SELECT *
FROM address
WHERE phone = '223664661973';
CREATE INDEX idx_address_phone
ON address(phone);
EXPLAIN SELECT *
FROM address
WHERE phone = '223664661973';
有时候尽管你创建了索引,但是由于表格较小等原因,查询优化器会自动的不使用索引来查询数据,那么就可以将索引干掉了。
语法·
DROP INDEX [ CONCURRENTLY]
[ IF EXISTS ] index_name (可以同时删除多个索引index1,index2....)
[ CASCADE | RESTRICT ];
CASCADE如果索引具有依赖对象,可以使用CASCADE选项来在删除索引时自动删除这该索引所依赖的对象RESTRICT如果有任何对象依赖该索引,RESTRICT选项指示 PostgreSQL 拒绝删除该索引,此选项为默认选项CASCADE如果索引具有依赖对象,您可以使用该CASCADE选项自动删除这些对象以及依赖于这些对象的所有对象。在PostgreSQL 中没有提供像SHOW INDEXES列出表或数据库的索引信息这样的命令。而是包含了一个默认的pg_indexes来存储索引信息,该视图由5个字段组成:
CREATE INDEX语句的形式存储索引定义命令。例如:查看数据库中public模式的所有索引:
SELECT * FROM
pg_indexes
WHERE
schemaname = 'public'
查询某个表的所有索引
SELECT
indexname,
indexdef
FROM
pg_indexes
WHERE
tablename = 'table_name';
使用psql 命令行查看索引:
\d table_name
该命令将返回表的所有信息,包括表的结构、索引、约束和触发器
PostgreSQL 有几种索引类型/方法:B-tree、Hash、GiST、SP-GiST、GIN 和 BRIN。每种索引类型使用不同的存储结构和算法来应对不同类型的查询。
当你使用CREATE INDEX语句而不指定索引类型时,PostgreSQL 默认使用 B-tree 索引类型,因为它最适合最常见的查询
除了一下的索引,还可以通过添加扩展的方式添加更多的新索引。
explain_test_db=# select * from pg_am;
oid | amname | amhandler | amtype
------+--------+----------------------+--------
2 | heap | heap_tableam_handler | t
403 | btree | bthandler | i
405 | hash | hashhandler | i
783 | gist | gisthandler | i
2742 | gin | ginhandler | i
4000 | spgist | spghandler | i
3580 | brin | brinhandler | i
(7 rows)
explain_test_db=#
B-tree 是一种自平衡树,它维护已排序的数据,并允许在对数logN时间复杂度内进行搜索、插入、删除和顺序访问
每当索引列涉及使用以下运算符之一的比较时,PostgreSQL 查询计划程序将考虑使用 B-tree 索引:
<
<=
=
>=
BETWEEN
IN
IS NULL
IS NOT NULL
此外,查询计划器可以将 B-tree 索引用于涉及模式匹配运算符的查询:如LIKE、~,例如:
column_name LIKE 'foo%'
column_name LKE 'bar%'
column_name ~ '^foo'
如果您已经开始使用索引来优化您的 PostgreSQL 数据库,那么 B-tree 通常是首选。
哈希索引只能处理简单的相等比较 (=)。这意味着每当索引列涉及使用等于(=)运算符的比较时,查询计划器query planner 将考虑使用哈希索引。
要创建哈希索引,请在子句中使用CREATE INDEX具有HASH索引类型的USING语句,如下所示:
CREATE INDEX index_name
ON table_name USING HASH (indexed_column);
反转索引,可以处理包含多个键的值,如数组等。GIN支持用户定义的索引策略,可通过定义GIN索引的特定操作符类型实现不同的功能。PostgreSQL的标准发布中包含了用于一维数组的GIN操作符类,比如,它支持包含操作符“@>”、被包含操作符“<@”、相等操作符“=”、重叠操作符“&&”,等等
当您将多个值存储在单个列中时,GIN 索引最有用,例如hstore、array、 jsonb 和 range 类型。
BRIN代表dexes中的块范围。与 B-tree 索引相比,BRIN 更小,维护成本更低。
BRIN 允许在非常大的表上使用索引,这在以前使用没有水平分区的 B-tree 是不切实际的。
BRIN 常用于具有线性排序顺序的列,例如销售订单表的创建日期列。
不是单独一种索引类型,而是一种架构,可以在这种架构上实现很多不同的索引策略。GiST索引定义的特定操作符可以用于特定索引策略。PostgreSQL的标准发布中包含了用于二维几何数据类型的GiST操作符类,比如,一个图形包含另一个图形的操作符“@>”,一个图形在另一个图形的左边且没有重叠的操作符“<<”,等等。
GiST 代表广义搜索树。GiST 索引允许构建通用树结构。GiST 索引在索引几何数据类型和全文搜索时很有用。
P-GiST是“Space-Partitioned GiST”的缩写,即空间分区GiST索引。它是从PostgreSQL9.2版本开始提供的一种新索引类型,主要是通过一些新的索引算法来提高GiST索引在某种情况下的性能。
SP-GiST 索引对于具有自然聚类元素且不是同等平衡树的数据最有用,例如 GIS、多媒体、电话路由和 IP 路由。
PostgreSQLUNIQUE(唯一键)索引强制一列或多列中值的唯一性。要创建UNIQUE索引,可以使用以下语法:
CREATE UNIQUE INDEX index_name
ON table_name(column_name, [...]);
请注意,只有 B 树索引可以声明为唯一索引。
为列定义UNIQUE索引时,该列不能存储具有相同值的多行。
如果UNIQUE为两列或多列定义索引,则这些列中的组合值不能在多行中重复。
PostgreSQL 将NULL 其视为不同的值,因此,您可以在具有索引NULL的列中拥有多个值
当您为表定义主键或唯一键约束时,PostgreSQL 会自动创建相应的UNIQUE索引
示例:
CREATE TABLE employees (
employee_id SERIAL PRIMARY KEY,
first_name VARCHAR(255) NOT NULL,
last_name VARCHAR(255) NOT NULL,
email VARCHAR(255) UNIQUE
);
此语句在PostgreSQL创建了俩个唯一键索引,一个是employee_id列,一个唯一键列email
查看该表的索引信息:
SELECT
tablename,
indexname,
indexdef
FROM
pg_indexes
WHERE
tablename = 'employees';
在这里插入图片描述
两个唯一键索引
通常,创建索引引用表的一个或多个列。但是我们也可以基于表达式创建一个索引,其中包括表列,并且这些情况被称为表达式索引。
表达式的索引也称为基于函数的索引。
创建语法:
CREATE INDEX index_name
ON table_name (expression);
expression:当我们指定索引表达式时,该表达式可以在SQL命令的Order BY或WHERE子句中指定注意,维护表达式的索引非常困难,因为 PostgreSQL 必须在插入或更新每一行时评估表达式,并将结果用于索引。因此,当检索速度比插入和更新速度更关键时,您应该在表达式上使用索引。
使用示例:
CREATE INDEX idx_ic_last_name
ON customer(LOWER(last_name));
现在,以不区分大小写的方式根据姓氏查找客户的查询将使用 index on 表达式,如下所示:
EXPLAIN
SELECT
customer_id,
first_name,
last_name
FROM
customer
WHERE
LOWER(last_name) = 'purdy';

如果您有使用常量值的常用WHERE条件,则部分索引很有用
语法:
CREATE INDEX index_name
ON table_name(column_list)
WHERE condition;
示例:
SELECT
customer_id,
first_name,
last_name,
email
FROM
customer
WHERE
active = 0;
要执行此查询,查询计划程序需要扫描customer表(可使用EXPLAIN语句查询)
可以通过为列创建索引来优化此查询,active如下所示:
CREATE INDEX idx_customer_active
ON customer(active);
该索引实现了它的目的,但是,它包含许多从未搜索过的行,即所有活跃客户。
要定义仅包含非活动客户的索引,请使用以下语句:
CREATE INDEX idx_customer_inactive
ON customer(active)
WHERE active = 0;
WHERE从现在开始,只要子句出现在查询中,PostgreSQL 就会考虑部分索引:
EXPLAIN SELECT
customer_id,
first_name,
last_name,
email
FROM
customer
WHERE
active = 0;
输出:

实际上,由于硬件故障或软件错误,索引可能会损坏并且不再包含有效数据。要恢复索引,可以使用以下REINDEX语句
REINDEX [ ( VERBOSE ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } name;
VERBOSE关键字是可选的。包括在内时,该语句会在重新索引每个索引时显示进度报告示例:
REINDEX INDEX index_name; //重新创建单个索引
REINDEX TABLE table_name; //重新创建表的多个索引
REINDEX SCHEMA schema_name; //重新创建模式中所有索引
REINDEX DATABASE database_name; //在特定数据库中重新创建所有索引
REINDEX SYSTEM database_name; //重新创建特定数据库中系统目录的所有索引
REINDEX与DROP INDEX&CREATE INDEX:
该REINDEX语句从头开始重建索引内容,其效果类似于删除和重新创建索引。但是,它们之间的锁定机制是不同的。
REINDEX声明:
DROP INDEX&CREATE INDEX语句:
DROP INDEX通过获取该表的排他锁来锁定索引所属表的写入和读取。CREATE INDEX语句将锁定写入,但不会从索引的父表中读取。但是,在创建索引期间读取可能会很昂贵。你可以在表的多个列上创建索引,该索引称为多列索引、复合索引、组合索引或级联索引。
一个表中最多有32个个列索引,可以在pg_config_manual.h修改该默认配置
只有 B-tree、GIST、GIN 和 BRIN 索引类型支持多列索引
定义多列索引时,应将WHERE子句中经常使用的列放在列列表的开头,将不常用的列放在条件后面。
创建语法:
CREATE INDEX index_name
ON table_name(a,b,c,...);
在上述语法中,PostgreSQL 优化器会在以下情况下考虑使用索引:
WHERE a = v1 and b = v2 and c = v3;
WHERE a = v1 and b = v2;
WHERE a = v1;
但是,它不会考虑在以下情况下使用索引:
WHERE c = v3;
WHERE b = v2 and c = v3;
示例:
CREATE TABLE people(
id INT GENERATED BY DEFAULT AS IDENTITY,
first_name VARCHAR(50) NOT NULL,
last_name VARCHAR(50) NOT NULL
);
CREATE INDEX idx_people_names
ON people (last_name, first_name);
EXPLAIN SELECT
*
FROM
people
WHERE
last_name = 'Adams'
AND first_name = 'Lou';
PostgreSQL 优化器为此语句使用了索引,因为WHERE子句中的两列都在索引中:

EXPLAIN SELECT
*
FROM
people
WHERE
first_name = 'Lou';
没有使用多列索引,因为last_name不在前面

在对查询性能进行故障排除时,应该查找以下几个项:
PostgreSQL 包含各种查询解释计划,包括纯文本和图形的。
PostgreSQL 与大多数关系数据库一样,允许查看实际执行计划和计划执行计划。
PostgreSQL 中有三个层次的解释计划:
EXPLAIN 不运行查询,而只是提供规划者可能采取的一般方法。当然,你几乎立刻就能得到最终的计划EXPLAIN ANALYZE运行查询,但不返回答案。它生成真实的计划和时间,而不返回结果EXPLAIN (ANALYZE,VERBOSE) 进行深入的计划分析,生成更多的信息,例如正在输出的列具体语法:
EXPLAIN [ ( option [, ...] ) ] statement
EXPLAIN [ ANALYZE ] [ VERBOSE ] statement
option
ANALYZE [ boolean ] -- ANALYZE选项通过实际执行SQL来获得SQL命令的实际执行计划。
VERBOSE [ boolean ] -- VERBOSE选项显示计划的附加信息,如计划树中每个节点输出的各个列,如果触发器被触发,还会输出触发器的名称。该选项的值默认为“FALSE”
COSTS [ boolean ] -- COSTS选项显示每个计划节点的启动成本和总成本,以及估计行数和每行宽度。该选项的值默认为“TRUE”
BUFFERS [ boolean ] -- BUFFERS选项显示缓冲区使用的信息。该参数只能与ANALYZE参数一起使用。显示的缓冲区信息包括共享块读和写的块数、本地块读和写的块数,以及临时块读和写的块数,默认为“FALSE”
FORMAT { TEXT | XML | JSON | YAML } -- FORMAT选项指定输出格式,输出格式可以是TEXT、XML、JSON或者YAML,默认为TEXT
文本解释器TEXTUAL EXPLAIN:
psql和pgadmin中查看图形解释器GRAPHICAL EXPLAIN:

SELECT t.town, r.rt_number
FROM
ch15.ma_towns AS t
INNER JOIN
ch15.ma_roads AS r
ON ST_Intersects(t.geom,r.geom)
WHERE r.rt_number = '9';

可以把鼠标停留在图标上,来获得相应节点的更多信息


explain_test_db=# select * from testtab01;
id | name
----+------
1 | hah
(1 row)
explain_test_db=# explain select * from testtab01;
QUERY PLAN
--------------------------------------------------------------
Seq Scan on testtab01 (cost=0.00..21.60 rows=1160 width=42)
(1 row)
explain_test_db=#
Seq Scan on testtab01(顺序全表扫描)cost=后面有两个数字,中间由..分隔,第一个数字0.00表示启动的成本,也就是说,返回第一行需要多少cost值;第二个数字表示返回所有数据的成本,rows=1160:表示会返回1160行width=42:表示每行平均宽度为42字节- 成本
cost用于描述SQL命令的执行代价,默认情况下,不同操作的cost值如下(根据下面的操作类型,PostgreSQL可以智能地计算出一个SQL命令的执行代价)
- 顺序扫描一个数据块,cost值定为
1- 随机扫描一个数据块,cost值定为
4- 处理一个数据行的CPU代价,cost值定为
0.01- 处理一个索引行的CPU代价,cost值定为
0.005- 每个操作符的CPU代价为
0.0025
explain_test_db=# explain (format json) select * from testtab01;
QUERY PLAN
-------------------------------------
[ +
{ +
"Plan": { +
"Node Type": "Seq Scan", +
"Parallel Aware": false, +
"Async Capable": false, +
"Relation Name": "testtab01",+
"Alias": "testtab01", +
"Startup Cost": 0.00, +
"Total Cost": 21.60, +
"Plan Rows": 1160, +
"Plan Width": 42 +
} +
} +
]
(1 row)
explain_test_db=# explain (format xml) select * from testtab01;
QUERY PLAN
----------------------------------------------------------
<explain xmlns="http://www.postgresql.org/2009/explain">+
<Query> +
<Plan> +
<Node-Type>Seq Scan</Node-Type> +
<Parallel-Aware>false</Parallel-Aware> +
<Async-Capable>false</Async-Capable> +
<Relation-Name>testtab01</Relation-Name> +
<Alias>testtab01</Alias> +
<Startup-Cost>0.00</Startup-Cost> +
<Total-Cost>21.60</Total-Cost> +
<Plan-Rows>1160</Plan-Rows> +
<Plan-Width>42</Plan-Width> +
</Plan> +
</Query> +
</explain>
(1 row)
explain_test_db=# explain (format YAML) select * from testtab01;
QUERY PLAN
--------------------------------
- Plan: +
Node Type: "Seq Scan" +
Parallel Aware: false +
Async Capable: false +
Relation Name: "testtab01"+
Alias: "testtab01" +
Startup Cost: 0.00 +
Total Cost: 21.60 +
Plan Rows: 1160 +
Plan Width: 42
(1 row)
添加“analyze”参数,通过实际执行来获得更精确的执行计划,命令如下
explain_test_db=# explain analyze select * from testtab01;
QUERY PLAN
---------------------------------------------------------------------------------------
Seq Scan on testtab01 (cost=0.00..21.60 rows=1160 width=42) (actual time=0.018..0.031 rows=1 loops=1)
Planning Time: 0.046 ms
Execution Time: 0.158 ms
(3 rows)
actual time=0.018..0.031 rows=1 loops=1实际启动时间为0.493毫秒,返回所有行的时间为4.320毫秒,返回的行数是10000同类写法:explain (analyze true )select * from testtab01;
联合使用analyze选项和buffers选项,通过实际执行来查看实际的代价和缓冲区命中的情况
explain_test_db=# explain (analyze true,buffers true ) select * from testtab01;
QUERY PLAN
--------------------------------------------------------------------------------------------------------
Seq Scan on testtab01 (cost=0.00..21.60 rows=1160 width=42) (actual time=0.014..0.029 rows=1 loops=1)
Buffers: shared hit=1
Planning Time: 0.038 ms
Execution Time: 0.075 ms
(4 rows)
因为加了buffers选项,执行计划的结果中就会出现一行“Buffers:shared hit=1 read=xxx written=yyy”,其中“shared hit=1”表示在共享内存中直接读到1个块,从磁盘中读到xxx块,写磁盘yyy块。
全表扫描就是把表中的所有数据块从头到尾读一遍,然后从中找到符合条件的数据块。
索引通常是为了加快查询数据的速度而增加的。索引扫描,就是在索引中找出需要的数据行的物理位置,然后再到表的数据块中把相应的数据读出来的过程。
索引扫描在EXPLAIN命令的输出结果中用“Index Scan”表示
位图扫描也是走索引的一种方式。方法是扫描索引,把满足条件的行或块在内存中建一个位图,扫描完索引后,再根据位图到表的数据文件中把相应的数据读出来。如果走了两个索引,可以把两个索引形成的位图通过AND或OR计算合并成一个,再到表的数据文件中把数据读出来。
当执行计划的结果行数很多时会走这种扫描,如非等值查询、IN子句或有多个条件都可以走不同的索引时。
非等值示例:
sdba=# explain select * from testtab02 where id2 >10000;
QUERY PLAN
--------------------------------------------------------------------------------
Bitmap Heap Scan on testtab02 (cost=18708.13..36596.06 rows=998155 width=16)
Recheck Cond: (id2 > 10000)
-> Bitmap Index Scan on idx_testtab02_id2 (cost=0.00..18458.59 rows=998155
width=0)
Index Cond: (id2 > 10000)
(4 rows)
Bitmap Index Scan先在索引中找到符合条件的行,然后在内存中创建位图,再到表中扫描,也就是我们看到的Bitmap Heap ScanRecheck Cond:(id2>10000),这是因为多版本的原因,从索引中找出的行从表中读出后还需要再检查一下条件。
IN子句走位图索引的示例:
osdba=# explain select * from testtab02 where id1 in (2,4,6,8);
QUERY PLAN
---------------------------------------------------------------------------------
Bitmap Heap Scan on testtab02 (cost=17.73..33.47 rows=4 width=16)
Recheck Cond: (id1 = ANY ('{2,4,6,8}'::integer[]))
-> Bitmap Index Scan on idx_testtab02_id1 (cost=0.00..17.73 rows=4 width=0)
Index Cond: (id1 = ANY ('{2,4,6,8}'::integer[]))
(4 rows)
走两个索引后将位图进行BitmapOr运算的示例:BitmapOr操作,即使用OR运算合并两个位图。
条件过滤,一般就是在WHERE子句上加过滤条件,当扫描数据行时会找出满足过滤条件的行。条件过滤在执行计划中显示为“Filter”
nyc=# explain select * from nyc_streets where id<50;
QUERY PLAN
----------------------------------------------------------------
Seq Scan on nyc_streets (cost=0.00..753.64 rows=49 width=184)
Filter: (id < '50'::double precision)
(2 行记录)
如果条件的列上有索引,可能会走索引而不走过滤
nyc=# explain select * from nyc_streets where gid<50;
QUERY PLAN
---------------------------------------------------------------------------
-------------
Index Scan using nyc_streets_pkey on nyc_streets (cost=0.29..10.14 rows=4
9 width=184)
Index Cond: (gid < 50)
(2 行记录)
参考:
https://www.postgresqltutorial.com
我发现自己需要这个。假设cart是一个包含用户列表的模型。defindex_of_itemcart.users.each_with_indexdo|u,i|ifu==current_userreturniendend获取此类关联索引的更简单方法是什么? 最佳答案 indexArray上的方法与您的index_of_item方法相同,例如cart.users.index(current_user)返回数组中第一个对象的索引==给obj。如果未找到匹配项,则返回nil。 关于ruby-on-
因此,当我遵循MichaelHartl的RubyonRails教程时,我注意到在用户表中,我们为:email属性添加了一个唯一索引,以提高find的效率方法,因此它不会逐行搜索。到目前为止,我们一直在根据情况使用find_by_email和find_by_id进行搜索。然而,我们从未为:id属性设置索引。:id是否自动索引,因为它在默认情况下是唯一的并且本质上是顺序的?或者情况并非如此,我应该为:id搜索添加索引吗? 最佳答案 大多数数据库(包括sqlite,这是RoR中的默认数据库)会自动索引主键,对于RailsMigration
我已经找到了几个使用datamapper的示例,并且能够让它们正常工作。不过,所有这些示例都是针对sqlite数据库的。我正在尝试将数据映射器与postgresql一起使用。我将datamapper中的调用从sqlite3更改为postgres,并且我已经安装了dm-postgres-adapter。但它仍然不起作用。我还需要做什么? 最佳答案 与SQLite不同,PostgreSQL不将数据库存储在单个文件中。在你拥有createdyourdatabase之后,尝试这样的事情:DataMapper.setup:default,{:
假设我有一个可枚举对象enum,现在我想获取第三个项目。我知道一种通用方法是转换成数组,然后使用索引访问,如:enum.to_a[2]但这种方式会创建一个临时数组,效率可能很低。现在我使用:enum.each_with_index{|v,i|breakvifi==2}但这非常丑陋和多余。执行此操作最有效的方法是什么? 最佳答案 你可以使用take剥离前三个元素,然后剥离last从take给你的数组中获取第三个元素:third=enum.take(3).last如果您根本不想生成任何数组,那么也许:#Ifenumisn'tanEnum
我找到了这样的东西:Rails:Howtolistdatabasetables/objectsusingtheRailsconsole?这一行没问题:ActiveRecord::Base.connection.tables并返回所有表但是ActiveRecord::Base.connection.table_structure("users")产生错误:ActiveRecord::Base.connection.table_structure("projects")我认为table_structure不是Postgres方法。如何列出Postgres数据库的Rails控制台中表中的所有
在我的场景中,Logstash收到的系统日志行的“时间戳”是UTC,我们在Elasticsearch输出中使用事件“时间戳”:output{elasticsearch{embedded=>falsehost=>localhostport=>9200protocol=>httpcluster=>'elasticsearch'index=>"syslog-%{+YYYY.MM.dd}"}}我的问题是,在UTC午夜,Logstash在外时区(GMT-4=>America/Montreal)结束前将日志发送到不同的索引,并且索引在20小时(晚上8点)之后没有日志,因为“时间戳”是UTC。我们已
我想使用PostgreSQL中的point类型。我已经完成了:railsgmodelTestpoint:point最终的迁移是:classCreateTests当我运行时:rakedb:migrate结果是:==CreateTests:migrating====================================================--create_table(:tests)rakeaborted!Anerrorhasoccurred,thisandalllatermigrationscanceled:undefinedmethod`point'for#/hom
我正在使用带有单个“帐户”表的STI模型来保存用户和技术人员的信息(即用户...8)错误:test_the_truth(用户测试):ActiveRecord::StatementInvalid:PGError:ERROR:关系“技术人员”不存在:从“技术人员”中删除...从本质上讲,标准框架不承认Technicians和Users表(或PostgreSQL称它们为“关系”)不存在,事实上,应该别名为Accounts。有什么想法吗?我对RoR比较陌生,不知道如何解决这个问题而又不完全删除STI。 最佳答案 原来问题是由于存在:./te
我正在使用PostgreSQL9.1.3(x86_64-pc-linux-gnu上的PostgreSQL9.1.3,由gcc-4.6.real(Ubuntu/Linaro4.6.1-9ubuntu3)4.6.1,64位编译)和在ubuntu11.10上运行3.2.2或3.2.1。现在,我可以使用以下命令连接PostgreSQLsupostgres输入密码我可以看到postgres=#我将以下详细信息放在我的config/database.yml中并执行“railsdb”,它工作正常。开发:adapter:postgresqlencoding:utf8reconnect:falsedat
我想从特定索引开始遍历数组。我该怎么做?myj.eachdo|temp|...end 最佳答案 执行以下操作:your_array[your_index..-1].eachdo|temp|###end 关于ruby-从特定索引开始迭代数组,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/44151758/