Cada fila de una tabla tiene una columna ctid
de tipo de sistematid
que representa la ubicación física de la fila:
create table t(id serial); insert into t default values; insert into t default values;
select ctid , id from t;
ctid | carné de identidad : ---- | -: (0,1) | 1 (0,2) | 2
dbfiddle aquí
¿Cuál es la mejor manera de obtener solo el número de página del ctid
tipo más apropiado (por ejemplo integer
, bigint
o numeric(1000,0)
)?
La única forma en que puedo pensar es muy fea.
postgresql
postgresql-9.4
datatypes
cast
data-pages
Jack Douglas
fuente
fuente
select ct[0], ct[1] from (select ctid::text::point as ct from pg_class where ...) y;
Respuestas:
Tu violín con mi solución.
@bma ya insinuó algo similar en un comentario. Aquí hay un ...
Justificación del tipo
ctid
es de tipotid
(identificador de tupla), llamadoItemPointer
en el código C. Por documentación:El énfasis en negrita es mío. Y:
Un bloque es de 8 KB en instalaciones estándar. El tamaño máximo de la mesa es de 32 TB . Se deduce lógicamente que los números de bloque deben acomodar al menos un máximo de (cálculo fijado según el comentario de @Daniel):
Lo que encajaría en un sin firmar
integer
. En una investigación adicional encontré en el código fuente que ...El énfasis en negrita es mío. Lo que confirma el primer cálculo:
Postgres usa un entero con signo y, por lo tanto, es un poco corto. No pude precisar, aún, si la representación de texto se desplaza para acomodar un entero con signo. Hasta que alguien pueda aclarar esto, recurriría a
bigint
, lo que funciona en cualquier caso.Emitir
No hay elenco registrado para el
tid
tipo en Postgres 9.3:Todavía puedes lanzar a
text
. Hay una representación de texto para todo en Postgres :La representación de texto coincide con la de un punto, que consta de dos
float8
números, ese reparto no tiene pérdidas.Puede acceder al primer número de un punto con índice 0. Transmitir a
bigint
. VoiláActuación
Realicé una prueba rápida en una tabla con 30k filas (la mejor de 5) en un par de expresiones alternativas que me vinieron a la mente, incluido el original:
int
en lugar debigint
aquí, mayormente irrelevante para el propósito de la prueba. No repetí parabigint
.El elenco para
t_tid
construir sobre un tipo compuesto definido por el usuario, como @Jake comentó.La esencia de esto: el casting tiende a ser más rápido que la manipulación de cuerdas. Las expresiones regulares son caras. La solución anterior es más corta y más rápida.
fuente
ctid
son 6 bytes con 4 para la página y 2 para la fila. Estaba preocupado por el casting,float
pero supongo que no necesito tener lo que dices aquí. Parece que un tipo compuesto definido por el usuario es mucho más lento que el usopoint
, ¿también lo encuentra?bigint
. Considera la actualización.point
y el regresoint8
son aún más rápidos). La conversión a tipos predefinidos siempre será un poco más rápida. Lo agregué a mi prueba para comparar. Lo haría(page_number bigint, row_number integer)
para estar seguro.2^40
es solo 1TB, no 32TB, que es2^45
dividido por2^13
da2^32
, por lo tanto, los 32 bits completos son necesarios para el número de página.bigint
para blkno