CHAR बनाम VARCHAR के लिए सूचकांक प्रदर्शन (पोस्टग्रेज)


16

इस उत्तर में ( /programming/517579/strings-as-primary-keys-in-sql-database ) एक टिप्पणी ने मेरी आँख पकड़ ली:

यह भी ध्यान रखें कि सूचकांक तुलना करते समय अक्सर CHAR और VARCHAR के बीच बहुत बड़ा अंतर होता है

क्या यह पोस्टग्रेज के लिए लागू / अभी भी लागू होता है?

मैंने ओरेकल पर यह दावा करते हुए पेज पाया कि CHARकम या ज्यादा के लिए एक उपनाम है VARCHARऔर इसलिए सूचकांक प्रदर्शन समान है, लेकिन मुझे पोस्टग्रेज पर कुछ भी निश्चित नहीं मिला।

जवाबों:


24

CHARऔर VARCHARपोस्टग्रेज (और ओरेकल) में बिल्कुल समान हैं। उन डेटा प्रकारों का उपयोग करते समय गति में कोई अंतर नहीं होता है।

हालांकि, एक अंतर है जो प्रदर्शन में अंतर कर सकता है : एक charकॉलम हमेशा परिभाषित लंबाई में गद्देदार होता है। इसलिए यदि आप किसी कॉलम को एक के रूप में char(100)और एक के रूप में परिभाषित varchar(100)करते हैं, लेकिन प्रत्येक में केवल 10 वर्णों को संग्रहीत करते हैं, तो char(100)स्तंभ प्रत्येक मान के लिए 100 वर्णों का उपयोग करता है (आपके द्वारा संग्रहीत 10 वर्ण, साथ ही 90 रिक्त स्थान), जबकि varcharस्तंभ केवल 10 वर्णों को संग्रहीत करता है।

100 वर्णों के साथ 100 वर्णों की तुलना 10 वर्णों के साथ 10 वर्णों की तुलना में धीमी होने वाली है - हालांकि मुझे संदेह है कि आप वास्तव में SQL क्वेरी में इस अंतर को माप सकते हैं।

यदि आप 10 वर्णों की लंबाई के साथ दोनों की घोषणा करते हैं और हमेशा उनमें ठीक 10 वर्ण संग्रहीत करते हैं, तो बिल्कुल कोई अंतर नहीं है (यह ओरेकल और पोस्टग्रेज के लिए सच है)

तो केवल अंतर पैडिंग है जो charडेटा प्रकार के लिए किया जाता है ।


यह भी ध्यान रखें कि सूचकांक तुलना करते समय अक्सर CHAR और VARCHAR के बीच बहुत बड़ा अंतर होता है

उपरोक्त उद्धरण केवल तभी सच है यदि (और केवल यदि) charस्तंभ बहुत व्यापक परिभाषित किया गया है (यानी आप पैडिंग के कारण अंतरिक्ष को बर्बाद कर रहे हैं)। यदि charकॉलम की लंबाई हमेशा पूरी तरह से उपयोग की जाती है (इसलिए कोई पेडिंग नहीं होती है), तो उपरोक्त उद्धरण गलत है (कम से कम पोस्टग्रैज और ओरेकल के लिए)


मेरे दृष्टिकोण से, charडेटा प्रकार का वास्तव में कोई वास्तविक शब्द उपयोग नहीं है। बस उपयोग करें varchar(या textपोस्टग्रेज में) और भूल जाएं कि charमौजूद है।


2
100 वर्णों के साथ 100 वर्णों की तुलना 10 वर्णों के साथ 10 वर्णों की तुलना में धीमी होने वाली है - हालांकि मुझे संदेह है कि आप वास्तव में SQL क्वेरी में इस अंतर को माप सकते हैं। - छँटाई के अलावा क्वेरी क्या करती है, इसके आधार पर, अंतर बहुत बड़ा हो सकता है। यही कारण है कि Postgres 9.5 में एक नई "संक्षिप्त कुंजियाँ" सुविधा है: pgeoghegan.blogspot.de/2015/01/…
chirlu

6

मैं a_horse_with_no_name द्वारा कही गई हर बात से सहमत हूं , और मैं आमतौर पर इरविन की टिप्पणी सलाह से सहमत हूं:

नहीं, चार अवर (और पुराना) है। पाठ और varchar प्रदर्शन (लगभग) वही।

मेटाडाटा

एक मामूली अपवाद के साथ, केवल समय मैं उपयोग char()है जब मैं मेटा डेटा इस कहना चाहता हूँ MUST किया है एक्स-अक्षर। हालांकि मुझे पता है कि char()केवल शिकायत है कि अगर इनपुट सीमा से अधिक है, तो मैं अक्सर एक CHECKबाधा में कमियों से रक्षा करूंगा । उदाहरण के लिए,

CREATE TABLE foo (
  x char(10) CHECK ( length(x) = 10 )
);
INSERT INTO foo VALUES (repeat('x', 9));

मैं कुछ कारणों से ऐसा करता हूं,

  1. char(x)कभी-कभी स्कीमा-लोडर के साथ निश्चित-चौड़ाई वाले कॉलम के रूप में अनुमान लगाया जाता है। यह निश्चित-चौड़ाई वाले तार के लिए अनुकूलित भाषा में अंतर कर सकता है।
  2. यह एक सम्मेलन स्थापित करता है जो समझ में आता है और इसे आसानी से लागू किया जाता है। मैं इस सम्मेलन से कोड उत्पन्न करने के लिए एक भाषा में एक स्कीमा-लोडर लिख सकता हूं।

मुझे ऐसा करने की एक मिसाल चाहिए,

  1. दो-अक्षर के राज्य संक्षिप्त रूप, हालांकि इस सूची की गणना की जा सकती है, मैं आमतौर पर इसे एक के साथ करूँगा ENUM
  2. वाहन पहचान संख्या
  3. मॉडल संख्या (निश्चित आकार की)

त्रुटियों पर

ध्यान दें कि कुछ लोग सीमा के दोनों ओर त्रुटि संदेशों की असंगति से असहज हो सकते हैं, लेकिन यह मुझे परेशान नहीं करता है

test=# INSERT INTO foo VALUES (repeat('x', 9));
ERROR:  new row for relation "foo" violates check constraint "foo_x_check"
DETAIL:  Failing row contains (xxxxxxxxx ).
test=# INSERT INTO foo VALUES (repeat('x', 11));
ERROR:  value too long for type character(10)

साथ इसके विपरीत varchar

इसके अलावा, मुझे लगता है कि उपरोक्त सुझाव लगभग हमेशा उपयोग केtext सम्मेलन के साथ वास्तव में अच्छी तरह से फिट बैठता है । तुम varchar(n)भी पूछते हो। मैं उस का उपयोग कभी नहीं । कम से कम, मुझे पिछली बार याद नहीं था कि मैं इस्तेमाल किया था varchar(n)

  • यदि किसी युक्ति में स्थिर-चौड़ाई वाला फ़ील्ड है जिस पर मुझे भरोसा है, तो मैं उपयोग करता हूं char(n),
  • अन्यथा, मैं textप्रभावी रूप से varchar(कोई सीमा नहीं) का उपयोग करता हूं

अगर मुझे एक युक्ति मिली जिसमें परिवर्तनशील-लंबाई वाली पाठ-कुंजियाँ थीं जो कि सार्थक थीं और मुझे भरोसा था कि मेरे पास अधिकतम-लंबाई है, तो मैं भी उपयोग करूँगा varchar(n)। हालाँकि, मैं उस मापदंड के अनुरूप कुछ भी नहीं सोच सकता।

अतिरिक्त नोट्स

संबंधित प्रश्नोत्तर:


1

PostgreSQL

sales_reporting_db=# create table x (y char(2));
CREATE TABLE
sales_reporting_db=# insert into x values ('Y');
INSERT 0 1
sales_reporting_db=# select '*' || y || '*' from x;
 ?column? 
----------
 *Y*

आकाशवाणी

SQL> create table x ( y char(2));

Table created.

SQL> insert into x values ('Y');

1 row created.

SQL> select '*' || y || '*' from x;

'*'|
----
*Y *

Postgresql रिक्त स्थान के साथ पैड नहीं किया।


यह सिर्फ पोस्टग्रेज में एक ऑप्टिकल भ्रम है। कोशिश करेंSELECT pg_column_size(y) FROM x;
dezso

-2

मुझे यह सबसे उपयोगी लगा, और एक तेज 3 लाइन स्पष्टीकरण:

से CHAR (एन) बनाम VARCHAR (एन) बनाम पाठ Postgres में

  • यदि आप किसी अज्ञात लंबाई के साथ कुछ पाठ संग्रहीत करना चाहते हैं, तो TEXTडेटा प्रकार का उपयोग करें ।
  • यदि आप किसी अज्ञात लंबाई के साथ कुछ पाठ संग्रहीत करना चाहते हैं, लेकिन आप अधिकतम लंबाई जानते हैं, उपयोग करें VARCHAR(n)
  • यदि आप ज्ञात सटीक लंबाई के साथ कुछ पाठ संग्रहीत करना चाहते हैं, तो उपयोग करें CHAR(N)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.