2012-11-02 38 views
13

PostgreSQL में,, रिकॉर्ड का आदेश दिया जाता है कि कैसे जब एकाधिक स्तंभों का एक संयोजन PRIMARY KEY के रूप में निर्दिष्ट किया जाता है के साथ एक मेज में रिकॉर्ड का आदेश क्या है?एक समग्र प्राथमिक कुंजी

यह धारणा है कि PostgreSQL प्राथमिक कुंजी के क्रम में रिकॉर्ड का आदेश देता है। क्या यह?

साथ ही, PostgreSQL के मामले में प्राथमिक कुंजी स्वचालित रूप से अनुक्रमित है?

उत्तर

36

यह प्रश्न गुमराह धारणा बनाता है कि प्राथमिक कुंजी बिल तालिका को लागू करती है। यह नहीं है PostgreSQL तालिकाओं में प्राथमिक कुंजी के साथ या उसके बिना कोई परिभाषित आदेश नहीं है; वे पेज ब्लॉक में व्यवस्थित पंक्तियों का "ढेर" हैं। वांछित होने पर प्रश्नों के ORDER BY खंड का उपयोग करके ऑर्डरिंग लगाई गई है।

आप सोच रहे होंगे कि PostgreSQL तालिकाओं सूचकांक उन्मुख टेबल प्राथमिक कुंजी क्रम में डिस्क पर संग्रहीत that're के रूप में जमा हो जाती है, लेकिन कैसे Pg काम करता है कि नहीं है। मुझे लगता है कि प्राथमिक कुंजी द्वारा व्यवस्थित इनो डीबी स्टोर्स टेबल (लेकिन चेक नहीं किया गया है), और यह किसी अन्य विक्रेता के डेटाबेस में वैकल्पिक रूप से "क्लस्टर इंडेक्स" या "इंडेक्स-संगठित टेबल" नामक सुविधा का उपयोग करके वैकल्पिक है। यह सुविधा वर्तमान में PostgreSQL द्वारा समर्थित नहीं है (कम से कम 9.3 के रूप में)।

ने कहा, PRIMARY KEY को UNIQUE अनुक्रमणिका का उपयोग करके कार्यान्वित किया गया है, और उस अनुक्रमणिका के लिए एक आदेश है। यह सूचकांक (और इसलिए प्राथमिक कुंजी) के बाएं कॉलम से आरोही क्रम में क्रमबद्ध है, जैसे कि यह ORDER BY col1 ASC, col2 ASC, col3 ASC; था। PostgreSQL में किसी भी अन्य बी-पेड़ (जीआईएसटी या जीआईएन से अलग) इंडेक्स के बारे में भी यही सच है, क्योंकि उन्हें b+trees का उपयोग करके लागू किया गया है।

CREATE TABLE demo (
    a integer, 
    b text, 
    PRIMARY KEY(a,b) 
); 

प्रणाली स्वतः के बराबर पैदा करेगा:

तो तालिका में

CREATE UNIQUE INDEX demo_pkey ON demo(a ASC, b ASC); 

यह आपको बताया जाता है जब आप एक मेज, जैसे बनाने के लिए:

regress=>  CREATE TABLE demo (
regress(>  a integer, 
regress(>  b text, 
regress(>  PRIMARY KEY(a,b) 
regress(> ); 
NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index "demo_pkey" for table "demo" 
CREATE TABLE 

तालिका की जांच करते समय आप इस सूचकांक को देख सकते हैं:

regress=> \d demo 
    Table "public.demo" 
Column | Type | Modifiers 
--------+---------+----------- 
a  | integer | not null 
b  | text | not null 
Indexes: 
    "demo_pkey" PRIMARY KEY, btree (a, b) 

आप इस सूचकांक पर प्राथमिक कुंजी के अनुसार तालिका को फिर से ऑर्डर करने के लिए CLUSTER कर सकते हैं, लेकिन यह एक बार का ऑपरेशन है। एक गैर-डिफ़ॉल्ट FILLFACTOR मुझे लगता है कि यह करने की कोशिश करेंगे की वजह से नहीं है, हालांकि अगर अंतरिक्ष पन्नों में नि: शुल्क - प्रणाली है कि आदेश को बनाए रखने के नहीं होंगे।

सूचकांक (लेकिन ढेर) के निहित आदेश का एक परिणाम यह है कि यह ज्यादा तेजी के लिए खोज करने के लिए है:

SELECT * FROM demo ORDER BY a, b; 
SELECT * FROM demo ORDER BY a; 

से:

SELECT * FROM demo ORDER BY a DESC, b; 

और न ये प्राथमिक कुंजी इंडेक्स का उपयोग कर सकते हैं, वे एक seqscan करेंगे जब तक कि आपके पास b पर कोई अनुक्रमणिका नहीं है:

SELECT * FROM demo ORDER BY b, a; 
SELECT * FROM demo ORDER BY b; 

यह becaues PostgreSQL अकेले (a) पर एक सूचकांक के रूप में लगभग के रूप में तेजी से (a,b) पर एक सूचकांक का उपयोग कर सकते है।यह (a,b) पर एक सूचकांक का उपयोग नहीं कर सकते हैं जैसे कि वह अकेले (b) पर एक सूचकांक थे - नहीं भी धीरे-धीरे, यह सिर्फ नहीं कर सकता।

DESC प्रविष्टि, कि एक पृष्ठ के लिए एक रिवर्स सूचकांक स्कैन, जो एक साधारण आगे सूचकांक स्कैन की तुलना में धीमी करना चाहिए का सवाल है। आप EXPLAIN ANALYZE में रिवर्स सूचकांक स्कैन के बहुत सारे देख रहे हैं और आप अतिरिक्त सूचकांक के प्रदर्शन लागत खर्च कर सकते हैं, तो आप DESC क्रम में मैदान पर एक सूचकांक बना सकते हैं।

यह WHERE खंड ही नहीं, ORDER BY लिए सच है। तुम अकेले WHERE b = 3 के लिए खोज करने के लिए WHERE a = 4 या WHERE a = 4 AND b = 3 लेकिन नहीं के लिए खोज करने के लिए (a,b) पर एक सूचकांक का उपयोग कर सकते हैं।

+0

तो, मुझे लगता है चाहिए कि वाम-पंथी स्तंभ के आधार पर खोज के सबसे तेजी से हो जाएगा सही (स्तंभों मैं बात कर रहा हूँ सभी स्तंभों कि प्राथमिक कुंजी के रूप में कर रहे हैं) के लिए कॉलम की तुलना में? –

+1

@ अभिषेक जैन सही; पीके के बाएं कॉलम का उपयोग करके (या दोनों कॉलम का उपयोग करने वाले लुकअप) इंडेक्स का उपयोग करेंगे, जबकि पीके * के दाएं कॉलम का उपयोग करके * इंडेक्स का उपयोग करने में सक्षम नहीं होगा। अगर आपको उस पर लुकअप करने की ज़रूरत है, तो प्राथमिक कॉलम पर दूसरी इंडेक्स बनाने में मदद मिल सकती है, या प्राथमिक कुंजी के ऑर्डर को उलट दें यदि आपको अकेले दूसरे कॉलम को देखने की आवश्यकता नहीं है। –

+2

@ अभिषेक जैन आपका स्वागत है। मैं दृढ़ता से आपको 'EXPLAIN ANALYZE' आदेश से परिचित होने के लिए सलाह देता हूं, और 'psql' कमांड शैल के साथ। दोनों आपको यह समझने में मदद करेंगे कि PostgreSQL कैसे बेहतर काम करता है, विश्लेषण कैसे किया जाता है, विभिन्न इंडेक्सिंग रणनीतियों का परीक्षण करें, आदि। Http://explain.depesz.com/ बड़ी और जटिल क्वेरी योजनाओं को समझने की कोशिश करते समय भी उपयोगी हो सकता है। –