Tüm değerler 36 karakter olduğunda, dizin araması char vs varchar ile belirgin şekilde daha hızlı olur mu


30

Tüm tablolar için birincil anahtar için hash tabanlı oluşturulan bir kimlik kullanan eski bir şema (sorumluluk reddi!) Var. Böyle bir kimliğin bir örneği:

922475bb-ad93-43ee-9487-d2671b886479

Bu yaklaşımı değiştirmenin olası bir umudu yoktur, ancak indeks erişimi ile performans düşüktür. Kenara bu olabilir nedenlerinden sayısız ayarlama, daha az optimal olmanın gibiydi fark ettim bir şey var - uzunluğunda tam 36 karakter olmak tüm birçok tablolardaki tüm id değerlerinin rağmen sütun türüdür varchar(36), değil char(36) .

Sütun tiplerini sabit uzunlukta değiştirmek, indeks sayfası başına giriş sayısındaki çok küçük bir artışın ötesinde, char(36)herhangi bir önemli endeks performansı avantajı sunar mı?

Yani, postgresler sabit uzunluklu tiplerle uğraşırken değişken uzunluklu tiplerden çok daha hızlı performans gösterir mi?

Lütfen eksi depolama tasarrufundan bahsetmeyin - bu, sütunlarda değişiklik yapmak için gereken ameliyatla karşılaştırıldığında önemli olmayacaktır.

Yanıtlar:


40

Hayır. Hiç kazanç yok . El kitabı açıkça belirtir :

İpucu: Bu üç tip arasında , boşluklu tip kullanıldığında artan depolama alanından ve uzunluk kısıtlamalı bir sütuna depolanırken uzunluğu kontrol etmek için birkaç ekstra CPU çevrimi dışında performans farkı yoktur . character(n)Diğer bazı veritabanı sistemlerinde performans avantajları olsa da, PostgreSQL'de böyle bir avantaj yoktur; Aslında character(n), ek depolama maliyetlerinden dolayı genellikle en düşük olanı üçtür. Çoğu durumda text veya character varyingbunun yerine kullanılmalıdır .

Cesur vurgu benim.

char(n)büyük ölçüde modası geçmiş, işe yaramaz bir türdür. İle sopa varchar(n). Uzunluğu zorlamanız gerekmiyorsa varcharveya textbiraz daha hızlı olursanız . Bir farkı ölçemezsin.

Ayrıca, tüm dizelerin uzunluğu tam olarak 36 karakter ise, hiçbir şekilde eksi bir tane bile depolama tasarrufu yoktur . Her ikisi de diskte ve RAM'de tam olarak aynı boydadır. pg_column_size()İle test edebilirsiniz (ifadede ve tablo sütununda).

İlgili:

Başka seçenekler istemedin ama ikiden bahsedeceğim:

  1. COLLATION- DB'nizi "C" harmanlamasıyla çalıştırmıyorsanız . Harmanlama genellikle göz ardı edilir ve muhtemelen pahalıdır. İpleriniz doğal bir dilde anlamlı görünmediğinden, COLLATIONkurallara uymanın bir anlamı yoktur . İlgili:

    COLLATE "C"Performans üzerindeki etkisini (diğerlerinin yanı sıra) karşılaştıran kapsamlı ölçüt :

  2. UUID , belli ki. Dize şüpheli bir şekilde UUID (32 onaltılık rakam ve 4 sınırlayıcı) gibi görünüyor. Bunları depolamak çok daha verimli olacaktıruuid, bu da çoklu yollardan daha hızlı olan ve yalnızca 16 baytlık olan -RAM'deki 37 baytınaksinechar(36)veyavarchar(36)(sınırlayıcılar olmadan, sadece 32 tanımlayıcı karakterde saklanan) veya 33 diskteki bayt sayısı. Ama hizalama dolgusu neden olur 40 byte ya birçok durumda yol.)COLLATIONİçin ilgisiz olacaktıruuidda veri türü.

    SELECT '922475bb-ad93-43ee-9487-d2671b886479'::uuid

    Bu yardımcı olabilir (son bölümler):

    Ayrıca bakınız:


bu, uzunluk kısıtlı bir char / varchar (n) 'nin kısıtlamayı kontrol etmek için CPU çevrimi harcayacağı anlamına gelirken, değişken uzunluktaki metin alanı metni, bu senaryoyu kazanan ve bu kazananı kazanan char'a kıyasla daha az erişilebilir bir şekilde ayrı ayrı depolar. bir parça metin içeren 10 milyon satır söylemeye değer bile
PirateApp

1
@PirateApp: char(n)Neredeyse hiçbir zaman hiçbir şekilde kazanmaz . Kullanmayın. Veri tipleri textve varchar(uzunluk değiştirici olmadan) ikili uyumludur ve aynı performans özelliklerini paylaşırlar. Postgres'te ikisinin de bir arada yaşamasının tarihsel nedenleri var. Dahili olarak, textstring türleri arasında "tercih edilen" tiptir (fonksiyon tipi çözünürlüğünü etkileyebilir). İşlemciyi varchar(n)zar zor zorlamak için işlem yapıyor . İhtiyacınız olduğunda bir uzunluk kısıtlaması kullanın . Eldeki durumda uuidgerçek kazanan.
Erwin Brandstetter
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.