{"id":34419,"date":"2019-10-31T21:58:13","date_gmt":"2019-10-31T18:58:13","guid":{"rendered":"https:\/\/prohoster.info\/blog\/ispolzuem-vse-vozmozhnosti-indeksov-v-postgresql\/"},"modified":"2019-10-31T21:58:13","modified_gmt":"2019-10-31T18:58:13","slug":"ispolzuem-vse-vozmozhnosti-indeksov-v-postgresql","status":"publish","type":"post","link":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/ispolzuem-vse-vozmozhnosti-indeksov-v-postgresql","title":{"rendered":"Aprovechando todas las capacidades de los \u00edndices en PostgreSQL","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Aprovechando todas las capacidades de los \u00edndices en PostgreSQL\" src=\"\/wp-content\/uploads\/2019\/05\/34a92715e0cfaff2519d1aea460592ea.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nEn el mundo de Postgres, los \u00edndices son cruciales para una navegaci\u00f3n eficaz a trav\u00e9s del almacenamiento de la base de datos (denominado \u00abheap\u00bb). Postgres no admite la CLUSTERING para esto, y la arquitectura MVCC provoca que se acumulen muchas versiones de la misma tupla. Por lo tanto, es muy importante saber crear y mantener \u00edndices eficaces para apoyar a las aplicaciones.<\/p>\n<p>Les presento algunos consejos para optimizar y mejorar el uso de los \u00edndices.<\/p>\n<p><i>Nota: las consultas que se muestran a continuaci\u00f3n funcionan en un <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/devrimgunduz\/pagila\">ejemplo no modificado de la base de datos pagila<\/a><\/noindex>.<\/i><br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h3>Uso de \u00edndices cubrientes (Covering Indexes)<\/h3>\n<p>\nAnalicemos una consulta para extraer direcciones de correo electr\u00f3nico de usuarios inactivos. En la tabla <code>customer<\/code> hay una columna <code>active<\/code>, y la consulta resulta ser sencilla:<\/p>\n<pre><code class=\"sql\">pagila=# EXPLAIN SELECT email FROM customer WHERE active=0;\n                        PLAN DE CONSULTA\n-----------------------------------------------------------\n Seq Scan en customer  (costo=0.00..16.49 filas=15 ancho=32)\n   Filtro: (active = 0)\n(2 filas)<\/code><\/pre>\n<p>\nLa consulta llama a un escaneo secuencial completo de la tabla. <code>customer<\/code>Creemos un \u00edndice para la columna <code>active<\/code>:<\/p>\n<pre><code class=\"sql\">pagila=# CREATE INDEX idx_cust1 ON customer(active);\nCREATE INDEX\npagila=# EXPLAIN SELECT email FROM customer WHERE active=0;\n                                 PLAN DE CONSULTA\n-----------------------------------------------------------------------------\n Escaneo de \u00cdndice usando idx_cust1 en customer  (costo=0.28..12.29 filas=15 ancho=32)\n   Condici\u00f3n del \u00cdndice: (active = 0)\n(2 filas)<\/code><\/pre>\n<p>\nAyud\u00f3, el escaneo posterior se convirti\u00f3 en &#171;<code>index scan<\/code>&#171;. Esto significa que Postgres escanear\u00e1 el \u00edndice &#171;<code>idx_cust1<\/code>&#171;, y luego continuar\u00e1 buscando en el mont\u00f3n de la tabla para leer los valores de otras columnas (en este caso, la columna <code>correo electr\u00f3nico<\/code>), que son necesarios para la consulta.<\/p>\n<p>En PostgreSQL 11, se introdujeron \u00edndices cubrientes. Estos permiten incluir una o varias columnas adicionales en el mismo \u00edndice; sus valores se almacenan en el almacenamiento de datos del \u00edndice.<\/p>\n<p>Si utiliz\u00e1ramos esta caracter\u00edstica y agreg\u00e1ramos el valor del correo electr\u00f3nico dentro del \u00edndice, entonces a Postgres no le necesitar\u00eda buscar en el heap de la tabla el valor. <code>correo electr\u00f3nico<\/code>Veamos si esto funcionar\u00e1:<\/p>\n<pre><code class=\"sql\">pagila=# CREATE INDEX idx_cust2 ON customer(active) INCLUDE (email);\nCREATE INDEX\npagila=# EXPLAIN SELECT email FROM customer WHERE active=0;\n                                    PLAN DE CONSULTA\n----------------------------------------------------------------------------------\n Escaneo Solo de \u00cdndice usando idx_cust2 en customer  (costo=0.28..12.29 filas=15 ancho=32)\n   Condici\u00f3n del \u00cdndice: (active = 0)\n(2 filas)<\/code><\/pre>\n<p>\n&#171;<code>Escaneo Solo de \u00cdndice<\/code>&#187; nos dice que ahora la consulta solo necesita un \u00edndice, lo que ayuda a evitar todas las operaciones de entrada\/salida en disco para leer el mont\u00f3n de la tabla.<\/p>\n<p>Hoy, los \u00edndices de cobertura solo est\u00e1n disponibles para los \u00e1rboles B. Sin embargo, en este caso, los esfuerzos de mantenimiento ser\u00e1n mayores.<\/p>\n<h3>Uso de \u00edndices parciales<\/h3>\n<p>\nLos \u00edndices parciales solo indexan un subconjunto de las filas de la tabla. Esto permite ahorrar en el tama\u00f1o de los \u00edndices y realizar escaneos m\u00e1s r\u00e1pidos.<\/p>\n<p>Supongamos que necesitamos obtener una lista de direcciones de correo electr\u00f3nico de nuestros clientes en California. La consulta ser\u00eda la siguiente:<\/p>\n<pre><code class=\"sql\">SELECT c.email FROM customer c\nJOIN address a ON c.address_id = a.address_id\nWHERE a.district = 'California';\nwhich has a query plan that involves scanning both the tables that are joined:\npagila=# EXPLAIN SELECT c.email FROM customer c\npagila-# JOIN address a ON c.address_id = a.address_id\npagila-# WHERE a.district = 'California';\n                              QUERY PLAN\n----------------------------------------------------------------------\n Hash Join  (cost=15.65..32.22 rows=9 width=32)\n   Hash Cond: (c.address_id = a.address_id)\n   -&gt;  Seq Scan on customer c  (cost=0.00..14.99 rows=599 width=34)\n   -&gt;  Hash  (cost=15.54..15.54 rows=9 width=4)\n         -&gt;  Seq Scan on address a  (cost=0.00..15.54 rows=9 width=4)\n               Filter: (district = 'California'::text)\n(6 rows)<\/code><\/pre>\n<p>\n\u00bfQu\u00e9 nos proporcionar\u00e1n los \u00edndices normales:<\/p>\n<pre><code class=\"sql\">pagila=# CREATE INDEX idx_address1 ON address(district);\nCREATE INDEX\npagila=# EXPLAIN SELECT c.email FROM customer c\npagila-# JOIN address a ON c.address_id = a.address_id\npagila-# WHERE a.district = 'California';\n                                      QUERY PLAN\n---------------------------------------------------------------------------------------\n Hash Join  (cost=12.98..29.55 rows=9 width=32)\n   Hash Cond: (c.address_id = a.address_id)\n   -&gt;  Seq Scan on customer c  (cost=0.00..14.99 rows=599 width=34)\n   -&gt;  Hash  (cost=12.87..12.87 rows=9 width=4)\n         -&gt;  Bitmap Heap Scan on address a  (cost=4.34..12.87 rows=9 width=4)\n               Recheck Cond: (district = 'California'::text)\n               -&gt;  Bitmap Index Scan on idx_address1  (cost=0.00..4.34 rows=9 width=0)\n                     Index Cond: (district = 'California'::text)\n(8 rows)<\/code><\/pre>\n<p>\nEscaneo <code>address<\/code> fue reemplazado por un escaneo de \u00edndice <code>idx_address1<\/code>, y luego se escane\u00f3 el mont\u00f3n <code>address<\/code>.<\/p>\n<p>Dado que esta es una consulta com\u00fan y necesita ser optimizada, podemos usar un \u00edndice parcial que solo indexe las filas con direcciones donde el distrito <code>\u2018California\u2019<\/code>:<\/p>\n<pre><code class=\"sql\">pagila=# CREATE INDEX idx_address2 ON address(address_id) WHERE district='California';\nCREATE INDEX\npagila=# EXPLAIN SELECT c.email FROM customer c\npagila-# JOIN address a ON c.address_id = a.address_id\npagila-# WHERE a.district = 'California';\n                                           QUERY PLAN\n------------------------------------------------------------------------------------------------\n Hash Join  (cost=12.38..28.96 rows=9 width=32)\n   Hash Cond: (c.address_id = a.address_id)\n   -&gt;  Seq Scan on customer c  (cost=0.00..14.99 rows=599 width=34)\n   -&gt;  Hash  (cost=12.27..12.27 rows=9 width=4)\n         -&gt;  Index Only Scan using idx_address2 on address a  (cost=0.14..12.27 rows=9 width=4)\n(5 rows)<\/code><\/pre>\n<p>\nAhora la consulta solo lee <code>idx_address2<\/code> y no toca la tabla <code>address<\/code>.<\/p>\n<h3>Uso de \u00edndices multivaluados (Multi-Value Indexes)<\/h3>\n<p>\nAlgunas columnas que necesitan ser indexadas pueden no contener un tipo de dato escalar. Tipos de columnas como <code>jsonb<\/code>, <code>arrays<\/code> y <code>tsvector<\/code> pueden contener valores compuestos o m\u00faltiples. Si necesita indexar tales columnas, generalmente tendr\u00e1 que buscar a trav\u00e9s de todos los valores individuales en estas columnas.<\/p>\n<p>Intentaremos encontrar los t\u00edtulos de todas las pel\u00edculas que contengan tomas de doblajes fallidos. En la tabla <code>film<\/code> hay una columna de texto llamada <code>special_features<\/code>. Si una pel\u00edcula tiene esta \"caracter\u00edstica especial\", entonces la columna contendr\u00e1 un elemento en forma de matriz de texto <code>Behind The Scenes<\/code>. Para buscar todas esas pel\u00edculas, necesitamos seleccionar todas las filas con \"Behind The Scenes\" en <b>cualquier <\/b>valor de la matriz <code>special_features<\/code>:<\/p>\n<pre><code class=\"sql\">SELECT title FROM film WHERE special_features @&gt; '{\"Behind The Scenes\"}';<\/code><\/pre>\n<p>\nEl operador de contenci\u00f3n <code>@&gt;<\/code> verifica si la parte derecha es un subconjunto de la parte izquierda.<\/p>\n<p>Plan de consulta:<\/p>\n<pre><code class=\"sql\">pagila=# EXPLAIN SELECT title FROM film\npagila-# WHERE special_features @&gt; '{\"Behind The Scenes\"}';\n                           PLAN DE CONSULTA\n-----------------------------------------------------------------\n Secuencia de escaneo en film  (costo=0.00..67.50 filas=5 ancho=15)\n   Filtro: (special_features @&gt; '{\"Behind The Scenes\"}'::text[])\n(2 filas)<\/code><\/pre>\n<p>\nQue solicita un escaneo completo de la tabla con un costo de 67.<\/p>\n<p>Veamos si un \u00edndice B-Tree nos ayuda:<\/p>\n<pre><code class=\"sql\">pagila=# CREATE INDEX idx_film1 ON film(special_features);\nCREATE INDEX\npagila=# EXPLAIN SELECT title FROM film\npagila-# WHERE special_features @&gt; '{\"Behind The Scenes\"}';\n                           PLAN DE CONSULTA\n-----------------------------------------------------------------\n Secuencia de escaneo en film  (costo=0.00..67.50 filas=5 ancho=15)\n   Filtro: (special_features @&gt; '{\"Behind The Scenes\"}'::text[])\n(2 filas)<\/code><\/pre>\n<p>\nEl \u00edndice ni siquiera fue considerado. El \u00edndice B-Tree no tiene conocimiento de la existencia de elementos individuales en los valores indexados.<\/p>\n<p>Necesitamos un \u00edndice GIN.<\/p>\n<pre><code class=\"sql\">pagila=# CREATE INDEX idx_film2 ON film USING GIN(special_features);\nCREATE INDEX\npagila=# EXPLAIN SELECT title FROM film\npagila-# WHERE special_features @&gt; '{\"Behind The Scenes\"}';\n                                PLAN DE CONSULTA\n---------------------------------------------------------------------------\n Escaneo de heap de bitmap en film  (costo=8.04..23.58 filas=5 ancho=15)\n   Condici\u00f3n de verificaci\u00f3n: (special_features @&gt; '{\"Behind The Scenes\"}'::text[])\n   -\u2013&gt;  Escaneo de \u00edndice de bitmap en idx_film2  (costo=0.00..8.04 filas=5 ancho=0)\n         Condici\u00f3n de \u00edndice: (special_features @&gt; '{\"Behind The Scenes\"}'::text[])\n(4 filas)<\/code><\/pre>\n<p>\nEl \u00edndice GIN permite la coincidencia de valores individuales con valores compuestos indexados, lo que reduce el costo del plan de consulta m\u00e1s de la mitad.<\/p>\n<h3>Eliminamos la duplicaci\u00f3n de \u00edndices.<\/h3>\n<p>\nLos \u00edndices se acumulan con el tiempo, y a veces un nuevo \u00edndice puede contener la misma definici\u00f3n que uno de los anteriores. Para obtener definiciones de \u00edndices legibles para humanos, se puede utilizar la vista del cat\u00e1logo <code>pg_indexes<\/code>. Tambi\u00e9n podr\u00e1s encontrar f\u00e1cilmente definiciones duplicadas:<\/p>\n<pre><code class=\"sql\"> SELECT array_agg(indexname) AS indexes, replace(indexdef, indexname, '') AS defn\n    FROM pg_indexes\nGROUP BY defn\n  HAVING count(*) &gt; 1;\nY aqu\u00ed est\u00e1 el resultado cuando se ejecuta en la base de datos pagila de stock:\npagila=#   SELECT array_agg(indexname) AS indexes, replace(indexdef, indexname, '') AS defn\npagila-#     FROM pg_indexes\npagila-# GROUP BY defn\npagila-#   HAVING count(*) &gt; 1;\n                                indexes                                 |                                defn\n------------------------------------------------------------------------+------------------------------------------------------------------\n {payment_p2017_01_customer_id_idx,idx_fk_payment_p2017_01_customer_id} | CREATE INDEX  ON public.payment_p2017_01 USING btree (customer_id\n {payment_p2017_02_customer_id_idx,idx_fk_payment_p2017_02_customer_id} | CREATE INDEX  ON public.payment_p2017_02 USING btree (customer_id\n {payment_p2017_03_customer_id_idx,idx_fk_payment_p2017_03_customer_id} | CREATE INDEX  ON public.payment_p2017_03 USING btree (customer_id\n {idx_fk_payment_p2017_04_customer_id,payment_p2017_04_customer_id_idx} | CREATE INDEX  ON public.payment_p2017_04 USING btree (customer_id\n {payment_p2017_05_customer_id_idx,idx_fk_payment_p2017_05_customer_id} | CREATE INDEX  ON public.payment_p2017_05 USING btree (customer_id\n {idx_fk_payment_p2017_06_customer_id,payment_p2017_06_customer_id_idx} | CREATE INDEX  ON public.payment_p2017_06 USING btree (customer_id\n(6 rows)\n<\/code><\/pre>\n<p><\/p>\n<h3>\u00cdndices de superconjunto (Superset Indexes)<\/h3>\n<p>\nEs posible que acumules muchos \u00edndices, uno de los cuales indexa un subconjunto de columnas que est\u00e1n indexadas por otros \u00edndices. Esto puede ser tanto deseable como no \u2014 un superconjunto puede resultar en que las consultas se realicen solo a trav\u00e9s de los \u00edndices, lo cual es bueno, pero tambi\u00e9n puede ocupar demasiado espacio, o la consulta para la cual se cre\u00f3 este superconjunto ya no se utiliza.<\/p>\n<p>Si necesitas automatizar la identificaci\u00f3n de tales \u00edndices, puedes comenzar con <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/catalog-pg-index.html\">pg_index<\/a><\/noindex> de la tabla <code>pg_catalog<\/code>.<\/p>\n<h3>\u00cdndices no utilizados<\/h3>\n<p>\nA medida que las aplicaciones que utilizan bases de datos evolucionan, tambi\u00e9n lo hacen las consultas que utilizan. Los \u00edndices agregados anteriormente pueden no ser utilizados por ninguna consulta. Cada vez que se escanea un \u00edndice, se marca por el administrador de estad\u00edsticas, y en la vista del cat\u00e1logo del sistema <code>pg_stat_user_indexes<\/code> se puede ver el valor <code>idx_scan<\/code>, que es un contador acumulativo. Hacer un seguimiento de este valor durante un per\u00edodo de tiempo (digamos, un mes) proporcionar\u00e1 una buena visi\u00f3n de qu\u00e9 \u00edndices no se utilizan y pueden ser eliminados.<\/p>\n<p>Aqu\u00ed hay una consulta para obtener los contadores actuales de escaneo de todos los \u00edndices en el esquema <code>'public'<\/code>:<\/p>\n<pre><code class=\"sql\">SELECT relname, indexrelname, idx_scan\nFROM   pg_catalog.pg_stat_user_indexes\nWHERE  schemaname = 'public';\ncon una salida como esta:\npagila=# SELECT relname, indexrelname, idx_scan\npagila-# FROM   pg_catalog.pg_stat_user_indexes\npagila-# WHERE  schemaname = 'public'\npagila-# LIMIT  10;\n    relname    |    indexrelname    | idx_scan\n---------------+--------------------+----------\n customer      | customer_pkey      |    32093\n actor         | actor_pkey         |     5462\n address       | address_pkey       |      660\n category      | category_pkey      |     1000\n city          | city_pkey          |      609\n country       | country_pkey       |      604\n film_actor    | film_actor_pkey    |        0\n film_category | film_category_pkey |        0\n film          | film_pkey          |    11043\n inventory     | inventory_pkey     |    16048\n(10 filas)<\/code><\/pre>\n<p><\/p>\n<h3>Recreaci\u00f3n de \u00edndices con menos bloqueos<\/h3>\n<p>\nCon frecuencia es necesario recrear \u00edndices, por ejemplo, cuando se expanden en tama\u00f1o, y recrearlos puede acelerar el escaneo. Tambi\u00e9n los \u00edndices pueden da\u00f1arse. Cambiar los par\u00e1metros del \u00edndice tambi\u00e9n puede requerir su recreaci\u00f3n.<\/p>\n<h3>Activamos la creaci\u00f3n paralela de \u00edndices<\/h3>\n<p>\nEn PostgreSQL 11, la creaci\u00f3n de un \u00edndice B-Tree es concurrente. Para acelerar el proceso de creaci\u00f3n, se pueden usar m\u00faltiples trabajadores trabajando en paralelo. Sin embargo, aseg\u00farate de que estos par\u00e1metros de configuraci\u00f3n est\u00e9n establecidos correctamente:<\/p>\n<pre><code class=\"sql\">SET max_parallel_workers = 32;\nSET max_parallel_maintenance_workers = 16;<\/code><\/pre>\n<p>\nLos valores predeterminados son demasiado bajos. Idealmente, estos n\u00fameros deber\u00edan aumentarse junto con la cantidad de n\u00facleos del procesador. Lee m\u00e1s en <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-ASYNC-BEHAVIOR\">la documentaci\u00f3n<\/a><\/noindex>.<\/p>\n<h3>Creaci\u00f3n de \u00edndices en segundo plano<\/h3>\n<p>\nPuedes crear un \u00edndice en segundo plano utilizando el par\u00e1metro <code>CONCURRENTLY<\/code> comando <code>CREAR \u00cdNDICE<\/code>:<\/p>\n<pre><code class=\"sql\">pagila=# CREATE INDEX CONCURRENTLY idx_address1 ON address(district);\nCREATE INDEX<\/code><\/pre>\n<p>Este procedimiento de creaci\u00f3n de \u00edndices difiere del habitual en que no requiere bloquear la tabla, lo que significa que no bloquea las operaciones de escritura. Por otro lado, toma m\u00e1s tiempo y consume m\u00e1s recursos.<\/p>\n<p>Postgres ofrece muchas opciones flexibles para la creaci\u00f3n de \u00edndices y formas de abordar cualquier caso particular, adem\u00e1s de proporcionar maneras de gestionar la base de datos en caso de un crecimiento explosivo de tu aplicaci\u00f3n. Esperamos que estos consejos te ayuden a hacer que las consultas sean r\u00e1pidas y que la base est\u00e9 lista para escalar.<br \/>\n<br \/>Fuente: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/mailru\/blog\/453046\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412 \u043c\u0438\u0440\u0435 Postgres \u0438\u043d\u0434\u0435\u043a\u0441\u044b \u043a\u0440\u0430\u0439\u043d\u0435 \u0432\u0430\u0436\u043d\u044b \u0434\u043b\u044f \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0439 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438 \u043f\u043e \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0443 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 (\u0435\u0433\u043e \u043d\u0430\u0437\u044b\u0432\u0430\u044e\u0442 \u00ab\u043a\u0443\u0447\u0430\u00bb, heap). Postgres \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0434\u043b\u044f \u043d\u0435\u0433\u043e \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u044e, \u0438 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 MVCC \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u0443 \u0432\u0430\u0441 \u043d\u0430\u043a\u0430\u043f\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043c\u043d\u043e\u0433\u043e \u0432\u0435\u0440\u0441\u0438\u0439 \u043e\u0434\u043d\u043e\u0433\u043e \u0438 \u0442\u043e\u0433\u043e \u0436\u0435 \u043a\u043e\u0440\u0442\u0435\u0436\u0430. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0447\u0435\u043d\u044c \u0432\u0430\u0436\u043d\u043e \u0443\u043c\u0435\u0442\u044c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0438 \u0441\u043e\u043f\u0440\u043e\u0432\u043e\u0436\u0434\u0430\u0442\u044c \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u0438\u043d\u0434\u0435\u043a\u0441\u044b \u0434\u043b\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439. \u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044e [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":25931,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-34419","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0412 \u043c\u0438\u0440\u0435 Postgres \u0438\u043d\u0434\u0435\u043a\u0441\u044b \u043a\u0440\u0430\u0439\u043d\u0435 \u0432\u0430\u0436\u043d\u044b \u0434\u043b\u044f.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/ispolzuem-vse-vozmozhnosti-indeksov-v-postgresql\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"es_ES\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0432\u0441\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u0432 \u0432 PostgreSQL | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412 \u043c\u0438\u0440\u0435 Postgres \u0438\u043d\u0434\u0435\u043a\u0441\u044b \u043a\u0440\u0430\u0439\u043d\u0435 \u0432\u0430\u0436\u043d\u044b \u0434\u043b\u044f.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/ispolzuem-vse-vozmozhnosti-indeksov-v-postgresql\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T18:58:13+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T18:58:13+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47 Aprovechamos todas las capacidades de los \u00edndices en PostgreSQL | ProHoster","description":"En el mundo de Postgres, los \u00edndices son extremadamente importantes para.","canonical_url":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/ispolzuem-vse-vozmozhnosti-indeksov-v-postgresql","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"es_ES","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0432\u0441\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u0432 \u0432 PostgreSQL | ProHoster","og:description":"\u0412 \u043c\u0438\u0440\u0435 Postgres \u0438\u043d\u0434\u0435\u043a\u0441\u044b \u043a\u0440\u0430\u0439\u043d\u0435 \u0432\u0430\u0436\u043d\u044b \u0434\u043b\u044f.","og:url":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/ispolzuem-vse-vozmozhnosti-indeksov-v-postgresql","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T18:58:13+00:00","article:modified_time":"2019-10-31T18:58:13+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"34419","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-21 19:13:20","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 13:52:22","updated":"2026-01-21 19:13:20","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts\/34419","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/comments?post=34419"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts\/34419\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media\/25931"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media?parent=34419"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/categories?post=34419"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/tags?post=34419"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}