Tengo una mesa:

CREATE TABLE users (
        id BIGSERIAL PRIMARY KEY,
        first_name varchar(255) NOT NULL,
        last_name varchar(255) NOT NULL,
        cell_id   BIGINT                  
        ...
)

Cell_id es un uint64 de s2 y puede representar cualquier posición en el planeta.

-> haga clic en aquí para una buena descripción de s2

Ahora me gustaría tener un índice en cell_id principalmente para usar un operador de igualdad.

CREATE INDEX user_position ON users (cell_id);

Pero ahora me temo que este índice se actualizará y consultará demasiado y, al final, dará lugar a puntos muertos.

Entonces tuve la idea de hacer algo como esto

CREATE INDEX user_position_even ON users (cell_id) WHERE user id % 2 = 0
CREATE INDEX user_position_odd ON users (cell_id) WHERE user id % 2 = 1

E incluso se pueden agregar más índices / escasez.

Ahora tengo algunas preguntas:

  1. ¿Postgres usará ambos índices cuando haga una consulta?
  2. ¿Ayudaría esto a mantener las actuaciones?
  3. ¿Estaba mal mi primera preocupación?
  4. ¿Debería tener tablas diferentes en lugar de índices?
  5. ¿Habría otra forma de hacerlo mejor?
2
Azr 16 ene. 2017 a las 14:36
1
Sus consultas, que no filtran la columna id (por ejemplo, solo consulta la tabla users por ubicación, también conocida como cell_id) no utilizarán ninguno de sus índices "agrupados". - Los índices por sí solos no causarán interbloqueos, por lo general, varias tablas están involucradas en interbloqueos.
 – 
pozs
16 ene. 2017 a las 14:58
1
Nota al margen: PostgreSQL no tiene un verdadero tipo de entero sin signo . Si puede solucionar esto en su cliente (por ejemplo, con alguna reinterpretación binaria), está bien, de lo contrario, podría usar alguna extensión, por ejemplo. pguint.
 – 
pozs
16 ene. 2017 a las 14:58
Gracias @pozs y sí, estoy usando reinterpretación binaria
 – 
Azr
16 ene. 2017 a las 16:08
En su primer comentario: Entonces, debido a que estoy usando la igualdad, ¿no se usaría el índice?
 – 
Azr
16 ene. 2017 a las 16:09
Mi punto es que las consultas con FROM users WHERE cell_id = $1 AND id % 2 = 0 ciertamente usarán ese índice, WHERE cell_id = $1 AND id = $2 podría usar uno de esos índices, pero solo WHERE cell_id = $1 no usará ninguno de esos índices.
 – 
pozs
16 ene. 2017 a las 16:35

1 respuesta

La mejor respuesta
  1. ¿Postgres usará ambos índices cuando haga una consulta?

Si bien postgresql ciertamente puede usar más de un índice en una tabla, su identificación será divisible por 2 o indivisible, por lo que solo se puede usar uno de estos índices.

  1. ¿Ayudaría esto a mantener las actuaciones?

Improbable. El tipo de índice predeterminado en postgresql es B-Tree y aquí prácticamente está haciendo parte de lo que haría el índice por usted, por su cuenta. Pero el punto de referencia es solo para estar seguro.

  1. ¿Estaba mal mi primera preocupación?

Yo diría que esto se llama optimización prematura. Los índices B-Tree son bastante buenos para manejarlo. Vuelve aquí si te encuentras en un punto muerto

Índices de árbol B, GiST y SP-GiST
Compartir a corto plazo / nivel de página exclusivo Los bloqueos se utilizan para el acceso de lectura / escritura. Las cerraduras se liberan inmediatamente después de que se recupere o inserte cada fila de índice. Estos tipos de índices proporcionan la mayor concurrencia sin condiciones de interbloqueo.

  1. ¿Debería tener tablas diferentes en lugar de índices?

No, Postgresql puede manejar tablas muy grandes. Si esto alguna vez se convierte en una preocupación. dividir.

  1. ¿Habría otra forma de hacerlo mejor?

No tienes algo que esté roto y necesite ser reparado. Vuelve cuando lo hagas.

0
a_horse_with_no_name 16 ene. 2017 a las 20:09
¡Ajá, optimización prematura! Ahora no puedo estar en desacuerdo contigo. Gracias por la respuesta, lo intentaremos con la forma sencilla por defecto y veremos si tenemos que mejorar.
 – 
Azr
16 ene. 2017 a las 16:02
También tengo que agregar que muchos de esos cell_id serán similares porque las ciudades. Por eso pensé que habría candados en las páginas. Pero esto ciertamente se verá mitigado por el hecho de que habrá muchas páginas.
 – 
Azr
16 ene. 2017 a las 16:06
O si reduzco el tamaño de una celda
 – 
Azr
16 ene. 2017 a las 16:14
Big int to int no supondrá una gran diferencia. Si le preocupa que haya cell_ids duplicados, la preocupación puede o no estar justificada en función de las consultas que ejecute en él. Creo que es mejor ejecutarlo durante unos días y publicar otra pregunta con la consulta completa que le parezca lenta y el resultado de explain analyze
 – 
e4c5
16 ene. 2017 a las 16:17
Owkay! :) servirá ! ¡Gracias por tu valioso tiempo!
 – 
Azr
16 ene. 2017 a las 16:21