Każdy wiersz w tabeli ma kolumnę systemową ctid
typu, tid
która reprezentuje fizyczną lokalizację wiersza:
create table t(id serial); insert into t default values; insert into t default values;
select ctid , id from t;
ctid | ID : ---- | -: (0,1) | 1 (0,2) | 2)
dbfiddle tutaj
Jaki jest najlepszy sposób na poruszanie się tylko numer strony jako od ctid
w najbardziej odpowiedni typ (np integer
, bigint
lub numeric(1000,0)
)?
Jedyny sposób mogę myśleć jest bardzo brzydka.
postgresql
postgresql-9.4
datatypes
cast
data-pages
Jack mówi, że spróbuj topanswers.xyz
źródło
źródło
select ct[0], ct[1] from (select ctid::text::point as ct from pg_class where ...) y;
Odpowiedzi:
Twój skrzypce z moim rozwiązaniem.
@bma już podpowiedział coś podobnego w komentarzu. Tutaj jest ...
Uzasadnienie dla tego typu
ctid
jest typutid
(identyfikator krotki), wywoływanyItemPointer
w kodzie C. Według dokumentacji:Odważny nacisk moje. I:
Blok ma 8 KB w standardowych instalacjach. Maksymalny rozmiar stołu to 32 TB . Logicznie wynika, że numery bloków muszą zawierać co najmniej maksimum (obliczenia ustalone zgodnie z komentarzem @Daniel):
Które pasowałoby do niepodpisanego
integer
. Podczas dalszych badań odkryłem w kodzie źródłowym, że ...Odważny nacisk moje. Co potwierdza pierwsze obliczenia:
Postgres używa liczby całkowitej ze znakiem i dlatego jest nieco krótszy. Nie mogłem jeszcze ustalić, czy reprezentacja tekstowa jest przesunięta, aby uwzględnić liczbę całkowitą ze znakiem. Dopóki ktoś tego nie wyjaśni, wrócę do
bigint
, co w każdym razie działa.Odlew
W Postgres 9.3 nie ma zarejestrowanej obsady dla tego
tid
typu:Nadal możesz przesyłać do
text
. W Postgres istnieje reprezentacja tekstowa :Reprezentacja tekstowa odpowiada reprezentacji punktu, który składa się z dwóch
float8
liczb, a rzutowanie jest bezstratne.Możesz uzyskać dostęp do pierwszej liczby punktów o indeksie 0. Przesyłaj do
bigint
. Voilá.Występ
Przeprowadziłem szybki test na stole z 30 tys. Wierszy (najlepiej 5) na kilku alternatywnych wyrażeniach, które przyszły mi do głowy, w tym na Twoim oryginale:
int
zamiastbigint
tutaj, w większości nieistotne dla celów testu. Nie powtarzałem się zabigint
.Rzutowanie
t_tid
opiera się na typie złożonym zdefiniowanym przez użytkownika, takim jak skomentował @Jake.Istota tego: casting jest zwykle szybszy niż manipulacja sznurkiem. Wyrażenia regularne są drogie. Powyższe rozwiązanie jest najkrótsze i najszybsze.
źródło
ctid
to 6 bajtów z 4 na stronie i 2 dla rzędu. Martwiłem się o casting,float
ale chyba nie muszę tego robić z tego, co tu mówisz. Wygląda na to, że typ kompozytowy zdefiniowany przez użytkownika jest znacznie wolniejszy niż użyciepoint
, czy też to uważasz?bigint
. Rozważ aktualizację.point
iz powrotemint8
jest jeszcze szybsze). Przesyłanie do predefiniowanych typów zawsze będzie nieco szybsze. Dodałem go do mojego testu, aby porównać. Zrobiłbym to(page_number bigint, row_number integer)
na pewno.2^40
jest tylko 1 TB, a nie 32 TB, co jest2^45
podzielone przez2^13
daje2^32
, dlatego dla numeru strony potrzebne są pełne 32 bity.bigint
do blkno