Setiap baris dalam tabel memiliki kolom ctid
tipe sistemtid
yang mewakili lokasi fisik baris:
create table t(id serial); insert into t default values; insert into t default values;
select ctid , id from t;
ctid | Indo : ---- | -: (0,1) | 1 (0,2) | 2
Aku di sini
Apa cara terbaik untuk mendapatkan nomor halaman dari jenis ctid
yang paling sesuai (mis. integer
, bigint
Atau numeric(1000,0)
)?
Satu- satunya cara yang bisa saya pikirkan adalah sangat jelek.
postgresql
postgresql-9.4
datatypes
cast
data-pages
Jack Douglas
sumber
sumber
select ct[0], ct[1] from (select ctid::text::point as ct from pg_class where ...) y;
Jawaban:
Biola Anda dengan solusi saya.
@ bma sudah mengisyaratkan sesuatu yang mirip dalam komentar. Ini adalah ...
Dasar pemikiran untuk tipenya
ctid
adalah tipetid
(tuple identifier), yang disebutItemPointer
dalam kode C. Per dokumentasi:Penekanan berani saya. Dan:
Satu blok adalah 8 KB dalam instalasi standar. Ukuran Tabel Maksimal adalah 32 TB . Secara logis berikut bahwa nomor blok harus mengakomodasi setidaknya maksimum (perhitungan ditetapkan sesuai dengan komentar oleh @Daniel):
Yang cocok dengan yang tidak ditandatangani
integer
. Pada penyelidikan lebih lanjut saya menemukan dalam kode sumber yang ...Penekanan berani saya. Yang mengkonfirmasi perhitungan pertama:
Postgres menggunakan integer bertanda tangan dan karenanya sedikit pendek. Saya tidak bisa menjelaskan, apakah representasi teks digeser untuk mengakomodasi integer yang ditandatangani. Sampai seseorang dapat membereskan ini, saya akan kembali ke
bigint
, yang bekerja dalam hal apa pun.Pemeran
Tidak ada pemeran terdaftar untuk
tid
jenis di Postgres 9.3:Anda masih bisa memilih
text
. Ada representasi teks untuk semua yang ada di Postgres :Representasi teks cocok dengan titik, yang terdiri dari dua
float8
angka, yang dilemparkan adalah lossless.Anda dapat mengakses angka pertama dari suatu titik dengan indeks 0. Cast to
bigint
. Voila.Performa
Saya menjalankan tes cepat di atas meja dengan baris 30rb (terbaik 5) pada beberapa ekspresi alternatif yang muncul di pikiran, termasuk yang asli:
int
alih-alih dibigint
sini, sebagian besar tidak relevan untuk tujuan tes. Saya tidak mengulanginyabigint
.Para pemain
t_tid
membangun berdasarkan tipe komposit yang ditentukan pengguna, seperti @Jake berkomentar.Inti dari itu: Casting cenderung lebih cepat daripada manipulasi string. Ekspresi reguler mahal. Solusi di atas adalah yang terpendek dan tercepat.
sumber
ctid
adalah 6 byte dengan 4 untuk halaman dan 2 untuk baris. Saya khawatir tentang casting untukfloat
tetapi saya kira saya tidak perlu dari apa yang Anda katakan di sini. Sepertinya tipe komposit yang ditentukan pengguna jauh lebih lambat daripada menggunakanpoint
, apakah Anda juga menemukannya?bigint
. Pertimbangkan pembaruan.point
dan kembali keint8
masih lebih cepat). Cast ke tipe yang sudah ditentukan akan selalu sedikit lebih cepat. Saya menambahkannya ke tes saya untuk membandingkan. Saya akan(page_number bigint, row_number integer)
memastikannya.2^40
hanya 1TB, bukan 32TB yang2^45
, yang dibagi dengan2^13
memberi2^32
, maka 32 bit penuh diperlukan untuk nomor halaman.bigint
untuk blkno