काउंट (*) बनाम काउंट (1) - एसक्यूएल सर्वर


738

बस सोच रहा था कि क्या आप में से कोई भी व्यक्ति उपयोग Count(1)करता है Count(*)और यदि प्रदर्शन में कोई उल्लेखनीय अंतर है या यदि यह सिर्फ एक विरासत की आदत है जो पिछले दिनों से आगे लाया गया है?

विशिष्ट डेटाबेस है SQL Server 2005


7
SQL सर्वर के बारे में पता नहीं है, लेकिन MySQL में कोई अंतर नहीं है। दूसरी ओर COUNT (स्तंभ) अलग है
ग्रेग

118
सच नहीं। COUNT (SomeColumn) केवल उन पंक्तियों की गिनती लौटाएगा जिनमें SomeColumn के लिए गैर-शून्य मान हैं। COUNT (*) और COUNT ('Foo') तालिका में कुल पंक्तियों को वापस कर देंगे।
स्टीव ब्रॉगबर्ग 3'09

1
आगे के विवरण के लिए इस चुनिंदा गिनती की
अली आद्रावी

4
वाह स्टीव और यहां मैं 5 साल में टीएसक्यूएल में गिनती (*) बनाम काउंट (कॉलमनाम) के बिना जाने। धन्यवाद
Harindaka

3
नोट भी COUNT(*)बनाम COUNT(1)बनामCOUNT(pk) का जवाब है - जो बेहतर है? । वहाँ भी COUNT(*)बनाम COUNT(column-name)- जो अधिक सही है? । अन्य डुप्लिकेट भी हो सकते हैं।
जोनाथन लेफ्लर

जवाबों:


598

इसमें कोई फर्क नही है।

कारण:

ऑन लाइन पुस्तकें कहती हैं " COUNT ( { [ [ ALL | DISTINCT ] expression ] | * } )"

"1" एक गैर-अशक्त अभिव्यक्ति है: इसलिए यह उसी के समान है COUNT(*)। आशावादी इसे पहचानता है कि यह क्या है: तुच्छ।

के रूप में ही EXISTS (SELECT * ...याEXISTS (SELECT 1 ...

उदाहरण:

SELECT COUNT(1) FROM dbo.tab800krows
SELECT COUNT(1),FKID FROM dbo.tab800krows GROUP BY FKID

SELECT COUNT(*) FROM dbo.tab800krows
SELECT COUNT(*),FKID FROM dbo.tab800krows GROUP BY FKID

वही IO, वही योजना, काम करता है

संपादित करें, अगस्त 2011

DBA.SE पर भी ऐसा ही सवाल

संपादित करें, दिसंबर 2011

COUNT(*)विशेष रूप से ANSI-92 में उल्लेख किया गया है (" Scalar expressions 125" के लिए देखें)

मामला:

a) यदि COUNT (*) निर्दिष्ट है, तो परिणाम T की कार्डिनैलिटी है।

यही है, एएनएसआई मानक इसे स्पष्ट रक्तस्राव के रूप में पहचानता है कि आपका क्या मतलब है। इस अंधविश्वास के कारणCOUNT(1) RDBMS विक्रेताओं द्वारा अनुकूलित किया गया है । अन्यथा इसका मूल्यांकन एएनएसआई के अनुसार किया जाएगा

b) अन्यथा, TX एकल-स्तंभ तालिका है जो T की प्रत्येक पंक्ति के लिए <मूल्य अभिव्यक्ति> को लागू करने और अशक्त मानों को समाप्त करने का परिणाम है। यदि एक या अधिक अशक्त मानों को समाप्त कर दिया जाता है, तो एक पूरा होने की स्थिति उठाई जाती है: चेतावनी-


73

SQL सर्वर में, ये कथन समान योजनाएँ उत्पन्न करते हैं।

लोकप्रिय राय के विपरीत, ओरेकल में वे भी करते हैं।

SYS_GUID() ओरेकल में काफी कम्प्यूटेशनल गहन कार्य है।

मेरे परीक्षण डेटाबेस में, पंक्तियों के t_evenसाथ एक तालिका है1,000,000

यह प्रश्न:

SELECT  COUNT(SYS_GUID())
FROM    t_even

48सेकंड के लिए चलाता है , क्योंकि फ़ंक्शन SYS_GUID()को यह सुनिश्चित करने के लिए प्रत्येक का मूल्यांकन करने की आवश्यकता है कि यह एक नहीं है NULL

हालाँकि, यह प्रश्न:

SELECT  COUNT(*)
FROM    (
        SELECT  SYS_GUID()
        FROM    t_even
        )

लेकिन 2सेकंड के लिए चलता है , क्योंकि यह मूल्यांकन करने की कोशिश भी नहीं करता है SYS_GUID()( *तर्क के बावजूद COUNT(*))


यह SYS_GUID()कम से कम (मेरा मतलब, बिल्कुल) एक बार उप-क्वेरी के लिए परिणाम वापस करने के लिए मूल्यांकन करना चाहिए , है ना?
asgs

@asgs: आपको ऐसा क्यों लगता है? COUNT(*)के मूल्यों पर कैसे निर्भर करता है SYS_GUID?
क्वासोई

अब जब आप पूछेंगे, मुझे यकीन नहीं है। मैंने सोचा कि COUNT(*)दौड़ना है, इसके लिए एक टेबल चाहिए, इसलिए सब-क्वेरी को एक जैसा काम करना चाहिए। अन्यथा, मैं के लिए एक तरह से नहीं दिख रहा है COUNT(*)एक सार्थक मान देने के लिए
asgs

1
@asgs: यह मानते हुए कि आप जानते हैं कि mapविधि क्या करती है, क्या आप देखते हैं कि ये दो अभिव्यक्तियाँ कैसे होती हैं: t_even.map(() => sys_guid()).lengthऔर t_even.lengthहमेशा एक ही मूल्य पर लौटेंगी? Oracle का ऑप्टिमाइज़र इसे देखने और mapभाग को अनुकूलित करने के लिए काफी स्मार्ट है ।
क्वासोनि

1
@asgs बिल्कुल बस एक छोटी सी सुधार: lengthकाफी पर निर्भर नहीं करता क्या संग्रह सिर्फ उसके तत्वों की संख्या पर, के होते हैं। यदि यह संख्या संग्रह के मेटाडेटा में संग्रहीत है (यह Oracle या अन्य आधुनिक RDBMS के लिए नहीं है, लेकिन पुराने MySQL के भंडारण इंजन, MyISAM के लिए मामला है), तो COUNT(*)बस मेटाडेटा से मान लेने की आवश्यकता होगी।
क्वासोई

65

जाहिर है, COUNT(*)और COUNT(1)होगा हमेशा एक ही परिणाम लौटने। इसलिए, यदि कोई दूसरे की तुलना में धीमा था, तो यह प्रभावी रूप से एक आशावादी बग के कारण होगा। चूँकि दोनों रूपों का उपयोग प्रश्नों में बहुत बार किया जाता है, इसलिए DBMS के लिए इस तरह के बग को अपरिचित बने रहने देने का कोई अर्थ नहीं होगा। इसलिए आप पाएंगे कि दोनों रूपों का प्रदर्शन सभी प्रमुख SQL DBMS में समान है (शायद)।


मैं इसे एक बग नहीं मानूंगा यदि गिनती (1) गिनती (*) से धीमी थी। यदि आप dbms को 1s जनरेट करने के लिए कहते हैं और उन लोगों को गिनते हैं जो अशक्त नहीं हैं, तो हाँ, यह रिकॉर्ड की गिनती होने के लिए उबलता है, लेकिन आप dbms से आपके द्वारा लिखे गए प्रत्येक बकवास का पता लगाने और उसे दरकिनार करने की उम्मीद नहीं कर सकते।
थोरस्टन केटनर

1
खैर, एक ऑप्टिमाइज़र अनुकूलन करने के लिए होता है और एक गिनती के लिए विचार करने के लिए सिर्फ 2 मामले हैं: अभिव्यक्ति जो अशक्त हो सकती है, अभिव्यक्ति जो कभी शून्य नहीं होगी: गिनती (1) उत्तरार्द्ध में गिरती है, इसलिए डीबीएमएस की कोई आवश्यकता नहीं है प्रश्न का उत्तर देने के लिए "1" उत्पन्न करें। (BTW मैं कभी भी कुछ भी नहीं बल्कि गिनती (*) का उपयोग करूंगा, सिर्फ सौंदर्य कारणों से।)
टोनी एंड्रयूज

46

मैं SQL सर्वर टीम पर काम करता हूं और मैं इस धागे में कुछ बिंदुओं को स्पष्ट रूप से स्पष्ट कर सकता हूं (मैंने इसे पहले नहीं देखा था, इसलिए मुझे खेद है कि इंजीनियरिंग टीम ने ऐसा पहले नहीं किया है)।

सबसे पहले, select count(1) from tableबनाम के बीच कोई शब्दार्थ अंतर नहीं है select count(*) from table। वे सभी मामलों में समान परिणाम लौटाते हैं (और यह बग नहीं तो)। जैसा कि अन्य उत्तरों में उल्लेख किया गया है, select count(column) from tableशब्दार्थ रूप से भिन्न है और हमेशा उसी तरह के परिणाम नहीं देता है count(*)

दूसरा, प्रदर्शन के संबंध में, SQL सर्वर (और SQL Azure) में दो पहलू होते हैं: संकलन-समय कार्य और निष्पादन-समय कार्य। संकलन समय काम वर्तमान कार्यान्वयन में एक तुच्छ छोटी मात्रा में अतिरिक्त काम है। कुछ कॉलमों में * से सभी कॉलमों का विस्तार होता है, जिसके बाद 1 कॉलम में कमी होती है और आउटपुट और ऑप्टिमाइज़ेशन में कुछ आंतरिक ऑपरेशन काम करते हैं। मुझे संदेह है कि यह किसी भी औसत दर्जे का परीक्षण में दिखाई देगा, और यह संभवतः अन्य सभी चीजों के शोर में खो जाएगा, जो कवर के तहत होता है (जैसे कि ऑटो-स्टैटिस, एक्सवेंट सत्र, क्वेरी स्टोर ओवरहेड, ट्रिगर्स, आदि)। यह शायद कुछ हजार अतिरिक्त सीपीयू निर्देश है। इसलिए, गणना (1) संकलन के दौरान एक छोटा सा कम काम करता है (जो आमतौर पर एक बार होता है और योजना बाद के कई निष्पादन में कैश की जाती है)। निष्पादन समय के लिए, यह मानते हुए कि योजनाएं समान हैं, कोई औसत दर्जे का अंतर नहीं होना चाहिए। (पहले के उदाहरणों में से एक में अंतर दिखाई देता है - यह मशीन पर अन्य कारकों के कारण सबसे अधिक संभावना है यदि योजना समान है)।

कैसे योजना संभावित रूप से भिन्न हो सकती है। ये होने की बहुत संभावना नहीं है, लेकिन वर्तमान ऑप्टिमाइज़र की वास्तुकला में यह संभव है। SQL सर्वर का ऑप्टिमाइज़र एक खोज कार्यक्रम के रूप में काम करता है (सोचो: क्वेरी के विभिन्न भागों के लिए विभिन्न विकल्पों के माध्यम से शतरंज खेलने वाले कंप्यूटर प्रोग्राम और उचित समय में सबसे सस्ती योजना खोजने के लिए विकल्पों की कीमत चुकाना)। इस खोज की कुछ सीमाएँ हैं कि यह क्वेरी संकलन को उचित समय में पूरा करने के लिए कैसे संचालित होता है। सबसे तुच्छ से परे के प्रश्नों के लिए, खोज के चरण हैं और वे प्रश्नों के ट्रान्स से निपटते हैं जो इस आधार पर करते हैं कि कैसे अनुकूलनकर्ता को लगता है कि क्वेरी संभावित निष्पादित करना है। 3 मुख्य खोज चरण हैं, और प्रत्येक चरण किसी भी पूर्व समाधान की तुलना में सस्ती योजना खोजने की कोशिश में अधिक आक्रामक (महंगी) ह्यूरिस्टिक्स चला सकता है। अंत में, प्रत्येक चरण के अंत में एक निर्णय प्रक्रिया होती है जो यह निर्धारित करने की कोशिश करती है कि उसे अब तक मिली योजना को वापस करना चाहिए या उसे खोजते रहना चाहिए। यह प्रक्रिया अब तक मिली सबसे अच्छी योजना की अनुमानित लागत बनाम अब तक के कुल समय का उपयोग करती है। इसलिए, सीपीयू की अलग-अलग गति वाली अलग-अलग मशीनों पर यह संभव है (यद्यपि दुर्लभ) अलग-अलग योजनाओं के लिए पहले चरण में एक योजना के साथ समय समाप्त होने के कारण बनाम अगले खोज चरण में जारी है। अंतिम चरण के समय से संबंधित कुछ समान परिदृश्य भी हैं और संभवतः बहुत, बहुत महंगे प्रश्नों पर मेमोरी से बाहर चल रहे हैं जो मशीन पर सभी मेमोरी का उपभोग करते हैं (आमतौर पर 64-बिट पर समस्या नहीं है, लेकिन यह एक बड़ी चिंता थी 32-बिट सर्वर पर वापस)। अंततः, यदि आपको एक अलग योजना मिलती है, तो रनटाइम पर प्रदर्शन अलग होगा। मैं डॉन'

नेट-नेट: कृपया उन दोनों में से जो भी आप चाहते हैं, उसका उपयोग किसी भी व्यावहारिक रूप में न करें। (ईमानदारी से, इस विषय से परे एसक्यूएल में प्रदर्शन को प्रभावित करने वाले बहुत बड़े कारक हैं)।

आशा है कि ये आपकी मदद करेगा। मैंने एक पुस्तक अध्याय लिखा था कि कैसे अनुकूलक काम करता है लेकिन मुझे नहीं पता कि क्या इसे यहाँ पोस्ट करना उचित है (क्योंकि मुझे इससे छोटे रॉयल्टी मिलते हैं फिर भी मुझे विश्वास है)। इसलिए, पोस्ट करने के बजाय, मैं यूके में SQLBits में दी गई एक बात का लिंक पोस्ट करूंगा कि कैसे अनुकूलक उच्च स्तर पर काम करता है ताकि आप खोज के विभिन्न मुख्य चरणों को थोड़ा और विस्तार से देख सकें यदि आप चाहें तो उस के बारे में जानने के लिए। यहां देखें वीडियो लिंक: https://sqlbits.com/Session/Event6/inside_the_sql_server_query_optimizer


2
मेरा विश्वास है कि 1यह भी उसी विस्तार से गुजरता है। मैं इसे संपूर्ण परीक्षणों पर आधारित करता हूं यहां stackoverflow.com/questions/1597442/…1 कॉलम में अनुमतियों के खेलने में अप्रत्याशित रूप से विफल होने का उपयोग करते हुए एक प्रश्न के उत्तर में भी उदाहरण देखें
मार्टिन स्मिथ

21

SQL-92 मानक में, COUNT(*)विशेष रूप से "टेबल एक्सप्रेशन की कार्डिनैलिटी" का अर्थ है (बेस टेबल, `व्यू, व्युत्पन्न टेबल, सीटीई, आदि) हो सकता है।

मुझे लगता है कि विचार यह था कि COUNT(*)पार्स करना आसान है। किसी भी अन्य अभिव्यक्ति का उपयोग करने के लिए पार्सर की आवश्यकता होती है ताकि यह सुनिश्चित किया जा सके कि यह किसी भी कॉलम का संदर्भ नहीं देता है ( COUNT('a')जहां aएक शाब्दिक है और COUNT(a)जहां aएक स्तंभ विभिन्न परिणाम दे सकता है)।

एक ही नस में, COUNT(*)एक मानक कोड SQL के साथ परिचित मानव कोडर द्वारा आसानी से उठाया जा सकता है, एक से अधिक विक्रेताओं के एसक्यूएल की पेशकश के साथ काम करते समय एक उपयोगी कौशल।

इसके अलावा, विशेष मामले में SELECT COUNT(*) FROM MyPersistedTable;, सोच यह है कि तालिका के कार्डिनलिटी के लिए आंकड़े रखने की संभावना है।

इसलिए, क्योंकि COUNT(1)और COUNT(*)शब्दार्थ समान हैं, मैं उपयोग करता हूं COUNT(*)


1
DBA.SE पर मेरे उत्तर से जुड़ा SQL-92 टेक्स्ट: dba.stackexchange.com/questions/2511/…
gbn


12

मुझे आशा है कि ऑप्टिमाइज़र यह सुनिश्चित करेगा कि अजीब किनारे के मामलों के बाहर कोई वास्तविक अंतर नहीं है।

किसी भी चीज़ की तरह, अपने विशिष्ट मामलों को मापने का एकमात्र वास्तविक तरीका है।

उसने कहा, मैंने हमेशा उपयोग किया है COUNT(*)


स्वीकृत उत्तर के अनुसार, यह MS SQL के लिए सही नहीं है - वास्तव में दोनों के बीच कोई अंतर नहीं है।
डेविड मैनहेम

10

जैसा कि यह सवाल बार-बार सामने आता है, यहां एक और जवाब है। मुझे लगता है कि "सर्वश्रेष्ठ अभ्यास" के बारे में सोचकर शुरुआती लोगों के लिए कुछ जोड़ने की उम्मीद है।

SELECT COUNT(*) FROM something रिकॉर्ड को गिनता है जो एक आसान काम है।

SELECT COUNT(1) FROM something 1 प्रति रिकॉर्ड प्राप्त करता है और 1s को मायने रखता है जो शून्य नहीं है, जो अनिवार्य रूप से रिकॉर्ड की गिनती कर रहा है, केवल अधिक जटिल है।

यह कहने के बाद: अच्छा डीबीएम यह नोटिस करता है कि दूसरा कथन पहले कथन के समान ही परिणाम देगा और अनावश्यक रूप से कार्य न करने के अनुसार इसे फिर से व्याख्या करेगा। इसलिए आमतौर पर दोनों वक्तव्यों को एक ही निष्पादन योजना में परिणाम मिलेगा और एक ही समय लगेगा।

हालाँकि पठनीयता के बिंदु से आपको पहले कथन का उपयोग करना चाहिए। आप रिकॉर्ड गिनना चाहते हैं, इसलिए रिकॉर्ड की गिनती करें, अभिव्यक्ति की नहीं। COUNT (अभिव्यक्ति) का उपयोग केवल तब करें जब आप किसी चीज़ की गैर-शून्य घटनाओं को गिनना चाहते हैं।


8

मैंने 8 जीबी रैम हाइपर-वी बॉक्स पर SQL सर्वर 2012 पर एक त्वरित परीक्षण चलाया। आप अपने लिए परिणाम देख सकते हैं। मैं इन परीक्षणों को चलाने के दौरान SQL सर्वर प्रबंधन स्टूडियो के अलावा किसी अन्य विंडो अनुप्रयोग को नहीं चला रहा था।

मेरी तालिका स्कीमा:

CREATE TABLE [dbo].[employee](
    [Id] [bigint] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](50) NOT NULL,
 CONSTRAINT [PK_employee] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

Employeeतालिका में रिकॉर्ड की कुल संख्या : 178090131 (~ 178 मिलियन पंक्तियाँ)

पहला प्रश्न:

Set Statistics Time On
Go    
Select Count(*) From Employee
Go    
Set Statistics Time Off
Go

प्रथम प्रश्न का परिणाम:

 SQL Server parse and compile time: 
 CPU time = 0 ms, elapsed time = 35 ms.

 (1 row(s) affected)

 SQL Server Execution Times:
   CPU time = 10766 ms,  elapsed time = 70265 ms.
 SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

दूसरी क्वेरी:

    Set Statistics Time On
    Go    
    Select Count(1) From Employee
    Go    
    Set Statistics Time Off
    Go

द्वितीय प्रश्न का परिणाम:

 SQL Server parse and compile time: 
   CPU time = 14 ms, elapsed time = 14 ms.

(1 row(s) affected)

 SQL Server Execution Times:
   CPU time = 11031 ms,  elapsed time = 70182 ms.
 SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

आप देख सकते हैं कि 83 (= 70265 - 70182) मिलीसेकंड का अंतर है जिसे प्रश्नों के चलने के समय आसानी से सटीक सिस्टम स्थिति के लिए जिम्मेदार ठहराया जा सकता है। इसके अलावा मैंने एक रन भी बनाया, इसलिए अगर मैं कई रन बनाऊं और कुछ औसत करूं तो यह अंतर और अधिक सटीक हो जाएगा। यदि इतने बड़े डेटा-सेट के लिए अंतर 100 मिलीसेकंड से कम हो रहा है, तो हम आसानी से यह निष्कर्ष निकाल सकते हैं कि दोनों प्रश्नों में SQL सर्वर इंजन द्वारा प्रदर्शित कोई प्रदर्शन अंतर नहीं है।

नोट : रैम दोनों रन में 100% उपयोग के करीब है। मैंने दोनों रन शुरू करने से पहले SQL सर्वर सेवा को फिर से शुरू किया।


7
SET STATISTICS TIME ON

select count(1) from MyTable (nolock) -- table containing 1 million records. 

SQL सर्वर निष्पादन समय:
CPU समय = 31 एमएस, बीता समय = 36 एमएस।

select count(*) from MyTable (nolock) -- table containing 1 million records. 

SQL सर्वर निष्पादन समय:
CPU समय = 46 एमएस, बीता समय = 37 एमएस।

मैंने इसे सैकड़ों बार चलाया है, हर बार कैश को साफ़ करता है .. परिणाम समय-समय पर भिन्न होते हैं क्योंकि सर्वर लोड बदलता रहता है, लेकिन लगभग हमेशा count(*)उच्चतर पीयूपी समय होता है।


14
मैं इसे पुन: पेश नहीं कर सकता। count(*)और count(1)मेरी SQL 2008 आवृत्ति में 4.5 मिलियन पंक्तियों के साथ एक तालिका की गिनती करते हुए भी एक दूसरे के कुछ एमएस के भीतर परिणाम लौटाएं।
जेफ एटवुड

2
कभी-कभी, कुछ प्रणालियों में, यह कथन सबसे पहले हमेशा तेज चलता है ... क्या आपने उस क्रम को यादृच्छिक बना दिया है जिसमें वे चलते हैं?
जोसेफडोगी

@ JosephDoggie को इस तरह के माप / आँकड़े लेते समय हर क्वेरी को चलाने से पहले हमेशा SQL सर्वर सेवा को पुनरारंभ करना चाहिए। जब आपने अभी SQL सर्वर सेवा शुरू की है, तो हर रन पूरी तरह से स्वतंत्र हो जाता है और क्वेरी के क्रम में कोई फर्क नहीं पड़ता। दूसरी ओर, यदि आप SQL सर्वर सेवा को पुनरारंभ नहीं करते हैं और इंजन निष्पादन योजनाओं की किसी प्रकार की कैशिंग करता है, तो बाद में चलाए जा रहे क्वेरी को पहले नहीं तेजी से चलाना चाहिए।
आरबीटी

तुलना करते समय निष्पादन समय को सटीक क्वेरी योजनाओं को देखना होगा। यदि वे अलग हैं (कहते हैं, हैश एग्रीगेट बनाम सॉर्ट + स्ट्रीम एग्रीगेट), तो परिणाम तुलनीय नहीं हैं। इसलिए, मैं अधिक आंकड़ों के बिना सावधानीपूर्वक निष्कर्ष निकालने का आग्रह करता हूं।
कॉनर कनिंघम MSFT

3

वहाँ एक है लेख दिखा रहा है कि COUNT(1)पर ओरेकल बस के लिए एक उपनाम है COUNT(*), एक साथ सबूत है कि के बारे में।

मैं कुछ हिस्सों को उद्धृत करूंगा:

डेटाबेस सॉफ़्टवेयर का एक हिस्सा है जिसे "द ऑप्टिमाइज़र" कहा जाता है, जिसे आधिकारिक प्रलेखन में "अंतर्निहित डेटाबेस सॉफ़्टवेयर" के रूप में परिभाषित किया गया है जो SQL कथन को निष्पादित करने का सबसे कुशल तरीका निर्धारित करता है।

ऑप्टिमाइज़र के घटकों में से एक को "ट्रांसफॉर्मर" कहा जाता है, जिसकी भूमिका यह निर्धारित करने के लिए है कि क्या मूल एसक्यूएल स्टेटमेंट को एक शब्दांश के समकक्ष एसक्यूएल स्टेटमेंट में फिर से लिखना लाभप्रद है जो अधिक कुशल हो सकता है।

क्या आप यह देखना चाहेंगे कि जब आप COUNT (1) का उपयोग करके क्वेरी लिखते हैं, तो ऑप्टिमाइज़र क्या करता है?

ALTER SESSIONविशेषाधिकार वाले उपयोगकर्ता के साथ , आप एक डाल सकते हैं tracefile_identifier, आशावादी अनुरेखण को सक्षम करें और COUNT(1)चयन करें, जैसे SELECT /* test-1 */ COUNT(1) FROM employees;:।

उसके बाद, आपको ट्रेस फ़ाइलों को स्थानीय बनाने की आवश्यकता है, जिसके साथ क्या किया जा सकता है SELECT VALUE FROM V$DIAG_INFO WHERE NAME = 'Diag Trace';। बाद में फ़ाइल पर, आप पाएंगे:

SELECT COUNT(*) COUNT(1)” FROM COURSE”.”EMPLOYEES EMPLOYEES

जैसा कि आप देख सकते हैं, यह सिर्फ एक उपनाम है COUNT(*)

एक अन्य महत्वपूर्ण टिप्पणी: ओरेकल 7.3 से पहले दो दशक पहलेCOUNT(*) वास्तव में तेज था ,

गणना (1) को 7.3 के बाद से गणना (*) में फिर से लिखा गया है क्योंकि ओरेकल ऑटो-ट्यूनिक पौराणिक बयानों को पसंद करता है। पहले ओरेकल 7 में, ओरेकल को प्रत्येक पंक्ति के लिए (1) एक फ़ंक्शन के रूप में मूल्यांकन करना पड़ता था, इससे पहले DETERMINISTIC और NON-DETERMINISTIC मौजूद हैं।

इसलिए दो दशक पहले, गिनती (*) तेज थी

Sql Server के रूप में अन्य डेटाबेस के लिए, इसे प्रत्येक के लिए अलग-अलग शोध किया जाना चाहिए।

मुझे पता है कि यह प्रश्न Sql Server के लिए विशिष्ट है, लेकिन इसी विषय पर SO के अन्य प्रश्न, डेटाबेस का उल्लेख किए बिना, बंद कर दिया गया था और इस उत्तर से डुप्लिकेट के रूप में चिह्नित किया गया था।


1

सभी RDBMS में, गिनती के दो तरीके उनके परिणाम के समान हैं। प्रदर्शन के बारे में, मैंने SQL सर्वर में कोई प्रदर्शन अंतर नहीं देखा है, लेकिन यह इंगित करने योग्य हो सकता है कि कुछ RDBMS, उदाहरण के लिए PostgreSQL 11, के पास कम इष्टतम कार्यान्वयन हैं COUNT(1)क्योंकि वे तर्क अभिव्यक्ति की अशक्तता की जांच करते हैं जैसा कि इस पोस्ट में देखा जा सकता है

मैंने दौड़ते समय 1M पंक्तियों के लिए 10% प्रदर्शन अंतर पाया है:

-- Faster
SELECT COUNT(*) FROM t;

-- 10% slower
SELECT COUNT(1) FROM t;

0

COUNT (1) COUNT (*) से पर्याप्त रूप से भिन्न नहीं है, यदि सभी में। COULLING NULLable COLUMNs के प्रश्न के रूप में, यह COUNT (*) और COUNT (<कुछ col>) के बीच के अंतरों को प्रदर्शित करने के लिए सीधा हो सकता है -

USE tempdb;
GO

IF OBJECT_ID( N'dbo.Blitzen', N'U') IS NOT NULL DROP TABLE dbo.Blitzen;
GO

CREATE TABLE dbo.Blitzen (ID INT NULL, Somelala CHAR(1) NULL);

INSERT dbo.Blitzen SELECT 1, 'A';
INSERT dbo.Blitzen SELECT NULL, NULL;
INSERT dbo.Blitzen SELECT NULL, 'A';
INSERT dbo.Blitzen SELECT 1, NULL;

SELECT COUNT(*), COUNT(1), COUNT(ID), COUNT(Somelala) FROM dbo.Blitzen;
GO

DROP TABLE dbo.Blitzen;
GO
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.