क्या यह वास्तव में संभव है कि इस विशेष निरर्थक व्युत्पन्न तालिका के लिए आदेश की गारंटी नहीं होगी?


12

मैं लुकास एडर के साथ ट्विटर पर हुई बातचीत पर इस सवाल पर अड़ गया

हालाँकि सही व्यवहार बाहरी क्वेरी पर ORDER BY क्लॉज़ को लागू करने के लिए होगा, क्योंकि, यहाँ, हम DISTINCT, GROUP BY, JOIN या किसी अन्य WHERE क्लॉज़ का सबसे बाहरी क्वेरी में उपयोग नहीं कर रहे हैं, तो RDDMS को पास क्यों नहीं किया जाएगा इनकमिंग क्वेरी द्वारा सॉर्ट किया गया आने वाला डेटा?

SELECT * 
FROM (
    SELECT * FROM table ORDER BY time DESC
) AS t

PostgreSQL पर इस उदाहरण को चलाते समय, कम से कम, आपको आंतरिक क्वेरी और इस व्युत्पन्न तालिका उदाहरण दोनों के लिए एक ही निष्पादन योजना मिलती है, साथ ही एक ही परिणाम सेट भी होता है।

इसलिए, मुझे लगता है कि प्लानर केवल सबसे बाहरी क्वेरी को छोड़ देगा क्योंकि यह निरर्थक है या केवल आंतरिक तालिका से परिणाम से गुजरता है।

क्या किसी को लगता है कि यह मामला नहीं हो सकता है?


4
ध्यान दें कि आपकी क्वेरी SQL सर्वर में विफल हो जाएगी क्योंकि एक व्युत्पन्न तालिका के अंदर एक आदेश की अनुमति नहीं है।
a_horse_with_no_name

आप इतने अविश्वासी क्यों हैं? आप कुछ भी क्यों मानेंगे? जब आप एक प्रोग्राम लिखते हैं जो आपको एक विकल्प छोड़ देता है तो क्या आप उपयोगकर्ताओं को अपनी पसंद के बारे में उम्मीद करते हैं? तार्किक और भौतिक क्वेरी अनुकूलन / कार्यान्वयन के बारे में पढ़ें।
फिलिप्पी

2
"मुझे लगता है कि प्लानर बस सबसे बाहरी क्वेरी को छोड़ देगा क्योंकि यह निरर्थक है या बस आंतरिक तालिका से परिणामों के माध्यम से गुजरता है।" आप आसानी से मान सकते हैं कि प्लानर आंतरिक क्वेरी पर ऑर्डरिंग क्लॉज को त्याग देगा क्योंकि यह संदर्भ में अर्थहीन है।
वाइल्डकार्ड

MariaDB, 2012 के बारे में, इस मुद्दे पर चर्चा करता है। समूहवार अधिकतम के लिएORDER BY अलग-अलग अनुकूलन के लिए आंतरिकनेतृत्वका अभाव।
रिक जेम्स

1
दरअसल, आप पोस्टग्रेज के लिए सही हैं।
इरविन ब्रान्डस्टेट्टर

जवाबों:


20

अधिकांश डेटाबेस इस तथ्य के बारे में काफी स्पष्ट हैं कि ORDER BYएक उपश्रेणी में या तो है:

  • अनुमति नहीं: उदाहरण के लिए SQL सर्वर, Sybase SQL कहीं भी (जब तक TOPया साथ पूरक नहीं है OFFSET .. FETCH)
  • अर्थहीन: उदाहरण के लिए PostgreSQL, DB2 (फिर से, जब तक कि साथ पूरक OFFSET .. FETCHया न हो LIMIT)

यहाँ DB2 LUW मैनुअल (जोर मेरा) से एक उदाहरण है

एक आदेश में एक खंड द्वारा खंड एक क्वेरी द्वारा लौटाए गए पंक्तियों के क्रम को प्रभावित नहीं करता है । एक आदेश द्वारा खंड केवल पंक्तियों के क्रम को प्रभावित करता है अगर यह बाहरी पूर्णता में निर्दिष्ट है।

शब्दांकन बिल्कुल स्पष्ट है, बिल्कुल PostgreSQL की तरह :

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

इस विनिर्देशन से, यह अनुसरण किया जा सकता है कि ORDER BYव्युत्पन्न तालिका में खंड से उत्पन्न कोई भी आदेश केवल आकस्मिक है और संयोगवश आपकी अपेक्षित ऑर्डर से मेल खा सकता है (जो यह आपके तुच्छ उदाहरण में अधिकांश डेटाबेस में करता है), लेकिन इस पर भरोसा करना नासमझी होगी। यह।

साइड नोट DB2 पर:

विशेष रूप से, DB2 में कम ज्ञात विशेषता हैORDER BY ORDER OF <table-designator> , जिसे निम्नानुसार उपयोग किया जा सकता है:

SELECT C1 FROM
   (SELECT C1 FROM T1
      UNION
    SELECT C1 FROM T2
    ORDER BY C1 ) AS UTABLE
ORDER BY ORDER OF UTABLE

इस विशेष मामले में, व्युत्पन्न तालिका के आदेश को स्पष्ट रूप से बाहरी सबसे अधिक चयन में फिर से उपयोग किया जा सकता है

ओरेकल पर साइड नोट:

वर्षों से यह ओरेकल में प्रचलन को लागू करने के लिए प्रचलन में OFFSETरहा है ROWNUM, जिसकी गणना एक व्युत्पन्न तालिका के आदेश के बाद ही की जा सकती है :

SELECT *
FROM (
  SELECT rownum AS rn, t.* -- ROWNUM here depends on the derived table's ordering
  FROM (
    SELECT * FROM table ORDER BY time DESC
  ) t
) t
WHERE rn BETWEEN 10 AND 20

यह उचित रूप से उम्मीद की जा सकती है कि कम से कम ROWNUMएक क्वेरी की उपस्थिति में , भविष्य के ओरेकल संस्करण इस व्यवहार को नहीं तोड़ेंगे ताकि सभी विरासत ऑरेकल एसक्यूएल को बहुत अधिक न तोड़ें, जो अभी तक बहुत अधिक वांछित नहीं है और पठनीय SQL मानक OFFSET .. FETCHवाक्यविन्यास:

SELECT * FROM table ORDER BY time DESC OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY

Meaningless: E.g. PostgreSQLवास्तव में होना चाहिए: 'अविश्वसनीय' है, क्योंकि यह करता है मतलब कुछ। पंक्तियों को आंतरिक क्वेरी में क्रमबद्ध किया जाता है, और उस आदेश को बाहरी क्वेरी स्तरों में रखा जाता है, जब तक कि अन्यथा निर्देश न दिया गया हो या अतिरिक्त संचालन के लिए पुन: क्रमबद्ध हो। यहां तक ​​कि अगर यह सिर्फ एक कार्यान्वयन विस्तार है, तो यह अर्थहीन नहीं है। इसका उपयोग कुल कार्यों के लिए छांटे गए इनपुट के लिए किया जा सकता है। मैनुअल भी उतना ही संकेत देता है: Alternatively, supplying the input values from a sorted subquery will usually work.
एरविन ब्रान्डसेट्टर

पोस्टग्रेज के लिए आपके द्वारा जोड़ा गया उद्धरण वास्तव में एक अलग मामले पर लागू होता है: ORDER BYबिल्कुल नहीं के साथ प्रश्न ।
एरविन ब्रान्डसेट्टर

@ErwinBrandstetter: उन विवरणों के साथ एक उत्तर जोड़ने के लिए स्वतंत्र महसूस करें। मैं व्यक्तिगत रूप से असहमत हूं कि कार्यान्वयन विवरण सार्थक हैं। बस आज, मैंने सीखा है कि पुराने दिनों में, लोग ओरेकल पर भरोसा करते थे, हमेशा ओरेकल 8 आई (मुझे विश्वास है) में ऑपरेशन द्वारा एक सॉर्ट किए गए समूह का प्रदर्शन करते हैं, जब अचानक, एक नए संस्करण ने हैशेड समूह को पेश किया, जिसने इस धारणा को तोड़ दिया कि कुछ निहित है आदेश देने पर भरोसा किया जा सकता है। दूसरे शब्दों में: मैं इसे बोल्ड शब्दों में रखना पसंद करता हूं। व्यर्थ , ओह के
लुकास ईडर

मैंने पहले ही एक उत्तर जोड़ दिया। क्या हमने गैर-मानक व्यवहार को अनदेखा करने के लिए चुना है या हमारे पास कौन सी अन्य अच्छी सलाह है: प्रश्न के लिए आदेश की गारंटी है? यह Postgres के लिए है। यह अन्य RDBMS के लिए (या लागू भी नहीं है)। और यह Postgres के सभी मौजूदा संस्करणों के लिए लागू होता है , न केवल संस्करण xyz के लिए, यह (आरक्षण के साथ) भी प्रलेखित है। आपकी बोली भ्रामक है। यदि हम गैर-मानक व्यवहार को अनदेखा करना चाहते हैं, तो हम Oracle के साथ शुरू कर सकते हैं जो हमें विश्वास दिलाता है कि रिक्त और खाली स्ट्रिंग समान हैं। प्रश्न के लिए भी orthogonal।
एरविन ब्रैंडस्टैटर

@ErwinBrandstetter: दिलचस्प, अपडेट के लिए धन्यवाद। क्या यह गारंटी है कि आप प्रलेखित की बात कर रहे हैं?
लुकास एडर

12

हाँ। एक ORDER BYखंड के बिना आउटपुट ऑर्डर अपरिभाषित है और क्वेरी प्लानर इसके दायरे में अच्छी तरह से मान लेता है कि आप इसे जानते और समझते हैं।

यह तय कर सकता है कि क्योंकि बाहरी क्वेरी एक आदेश को निर्दिष्ट नहीं करती है, यह एक प्रकार के ऑपरेशन से बचने के लिए आंतरिक क्वेरी में ऑर्डर को छोड़ सकता है, खासकर अगर ऑर्डर करने के लिए कोई क्लस्टर इंडेक्स या कोई इंडेक्स नहीं है। ऐसा नहीं होता है अब यह भविष्य के संस्करणों में ऐसा कर सकते हैं।

अपरिभाषित व्यवहार पर कभी भी भरोसा न करें। यदि आपको एक विशिष्ट आदेश देने की आवश्यकता है, ORDER BYतो उचित स्थान पर एक खंड दें ।


जब इसे PostgreSQL पर परीक्षण किया गया, तो क्रमबद्ध स्कैन के बाद छँटाई की गई क्योंकि मेरे पास ORDER BY द्वारा उपयोग किए गए कॉलम पर कोई इंडेक्स नहीं था। कौन सा RDBMS आपको लगता है कि आंतरिक क्वेरी ORDER BY को छोड़ देगा?
व्लाद मिहालसी

5
मैं यह नहीं कह सकता कि मुझे कोई भी पता होगा , बस यह कि वे किसी भी और सभी पूरी तरह से ऐसा करने के लिए स्वतंत्र हैं यदि वे चाहें - यह सामान्य मानकों और उत्पाद विनिर्देशों दोनों के अनुसार पूरी तरह से स्वीकार्य अनुकूलन होगा। SQL सर्वर क्वेरी को एक सिरे से अस्वीकार कर देगा (जब तक कि आप इसमें शामिल TOP 100%नहीं होते हैं कि वर्तमान क्वेरी पोर्टेबल नहीं है, तो क्या यह आपकी परियोजना के लिए प्राथमिकता होनी चाहिए। क्योंकि पोस्टग्रैड्स आंतरिक क्वेरी में आदेश का पालन करता है, इसका मतलब यह नहीं है कि यह हमेशा भविष्य में होगा (या) पुराने संस्करण वास्तव में ऐसा करते हैं) इसलिए आपको केवल मामले में व्यवहार पर भरोसा करने से बचना चाहिए।
डेविड स्पिललेट

1
@VladMihalcea एक डीबीएमएस जो अनावश्यक रूप ORDER BYसे "ऑप्टिमाइज़" करता है, वह है MariaDB: क्यों ओर से एक आदेश में उपेक्षित है?
ypercube y

6

अपरिभाषित व्यवहार के साथ इसकी बहुत समस्या है - आपके लिए काम करता है, मेरे लिए काम करता है, एचडीडी में सुधार करता है;)

हम एक कदम पीछे ले जा सकते हैं और कह सकते हैं कि एक अर्थ में आप सही हैं - ऐसा कोई सांसारिक कारण नहीं है कि कोई भी sn RDBMS आंतरिक चयन में पंक्तियों को फिर से व्यवस्थित करेगा। लेकिन इसकी गारंटी नहीं है - इसका मतलब है कि भविष्य में एक कारण हो सकता है, और विक्रेता ऐसा करने के लिए स्वतंत्र हैं। मतलब कि कोई भी कोड जो इस व्यवहार पर निर्भर करता है, एक बदलाव की दया पर है जो एक विक्रेता बना सकता है जिसे वे प्रचार के लिए बाध्य नहीं करेंगे, क्योंकि यह एपीआई पीओवी से एक ब्रेकिंग परिवर्तन नहीं है।


2
एक कारण यह आदेश का अनुकूलन कर सकता है गति है। एक अलग क्रम में पंक्तियों को वापस करना अधिक कुशल हो सकता है।
टॉमटॉम

2
विशेष रूप से, तालिका पढ़ने के लिए सर्वर समानता का शोषण कर सकता है। यदि ऐसा होता है, और किसी आदेश को लागू करने की आवश्यकता नहीं है, तो आपको पंक्तियाँ वापस मिल जाएंगी, लेकिन धागे उन्हें पढ़ते हैं। (एसक्यूएल सर्वर वास्तव में ऐसा करता है, ताकि SELECTकोई ORDER BYसही मायने में nondeterministic न हो, और न केवल सिद्धांत में या क्योंकि डेटा बदल गया है।)
Jeroen Mostert

@JeroenMostert: अपरिभाषित व्यवहार केवल बदतर हो जाता है। यदि यह क्रम से बाहर हो जाता है और डेल्टा एक सरणी में अनुक्रमित करने के लिए उपयोग किया जाता है तो क्या होता है?
जोशुआ

2

क्या यह वास्तव में संभव है कि इस विशेष निरर्थक व्युत्पन्न तालिका के लिए आदेश की गारंटी नहीं होगी?

वर्तमान में मौजूद सभी पोस्टग्रेज (जो आप परीक्षण कर रहे थे) के लिए इसका उत्तर है: इस विशेष क्वेरी के लिए नहीं -। सॉर्ट ऑर्डर की गारंटी है।

SQL सर्वर के लोग इससे असहज होंगे क्योंकि Microsoft ORDER BYउपश्रेणियों में भी अनुमति नहीं देता है। फिर भी पोस्टग्रेज में इस साधारण क्वेरी के लिए सॉर्ट ऑर्डर की गारंटी है। ORDER BYउपकुंजी में लागू किया जाता है, और बाहरी क्वेरी ऐसा कुछ भी नहीं करती है जो आदेश को बदल सकती है।

अध्याय एग्रीगेट फंक्शंस में भी मैनुअल उतना ही संकेत देता है :

वैकल्पिक रूप से, एक हल उपकुंजी से इनपुट मानों की आपूर्ति आमतौर पर काम करेगी।

ध्यान दें कि यह केवल सत्य है जबकि बाहरी क्वेरी स्तर परिचालन को नहीं जोड़ता है जो क्रम बदल सकता है। तो यह केवल साधारण मामले के लिए "गारंटी" है, और यह SQL मानक द्वारा समर्थित नहीं है। यदि यह अतिरिक्त परिचालनों के लिए उपयुक्त है तो पोस्टग्रेट्स फिर से चालू करने के लिए स्वतंत्र है। संदेह के मामले में ORDER BYबाहरी में एक और जोड़ें SELECT। ( ORDER BYइस साधारण क्वेरी के लिए आंतरिक कौन से मामले में अनावश्यक शोर होगा।)


क्या यह सच है जब "table"एक सरल, आधार तालिका नहीं बल्कि एक जटिल दृश्य या एक विभाजन तालिका है? क्या यह सच है जब योजना का समानांतर निष्पादन है, भी? क्या यह Postgres 10 में भी सच है? (मैं केवल पूछ रहा हूं, मैं इनमें से किसी भी सवाल के जवाब के लिए निश्चित नहीं हूं।)
ypercubeᵀᴹ

@ ypercube y: मैंने इन सभी के लिए पोस्टग्रेज 10 का परीक्षण नहीं किया है, लेकिन मुझे पूरा यकीन है कि यह किसी भी मामले में सच है। आदेश लागू होता है और साधारण मामले के लिए बाहरी क्वेरी में नहीं बदला जाता है।
एरविन ब्रान्डसेट्टर १
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.