SQL काउंट क्वेरी की गति क्या हो सकती है?


9

जब एक गणना (कुल) एसक्यूएल क्वेरी करते हैं, तो इन 3 डेटाबेस सिस्टम में निष्पादन समय की गति क्या हो सकती है? मुझे यकीन है कि कई चीजें इसे गति दे सकती हैं (एक के लिए हार्डवेयर), लेकिन मैं सिर्फ एक नौसिखिया डीबीए हूं, इसलिए मुझे यकीन है कि मुझे यहां कुछ उत्तर मिलेंगे। मैंने लगभग 157 मिलियन पंक्तियों को SQL सर्वर डेटाबेस में स्थानांतरित कर दिया, और यह क्वेरी हमेशा के लिए ले रही है। लेकिन मेरे स्रोत Netezza डेटाबेस में, कुछ सेकंड लगते हैं।

उदाहरण के लिए:

नेटिज़ज़ा 6:

SELECT COUNT(*) FROM DATABASENAME..MYTABLE

Oracle 11g:

SELECT COUNT(*) FROM MYTABLE

SQL सर्वर 2012:

SELECT COUNT(*) FROM DATABASENAME.[dbo].[MYTABLE]

इस प्रश्न को देख सकते हैं: stackoverflow.com/questions/11130448/sql-count-performance

1
क्या आपको केवल एक बार या बार-बार ऐसा करने की आवश्यकता है?
जॉन सीगेल

@JonSeigel हम वृद्धिशील भार कर रहे हैं, और हम प्रतिदिन डेटाबेस सिस्टम के बीच रिकॉर्डों की तुलना कर रहे हैं ताकि यह सुनिश्चित किया जा सके कि गिनती बढ़ रही है। तो बार-बार।
मैकगिवेर

जवाबों:


10

Netezza एक उपकरण है जिसे बड़े टेबल स्कैन में उत्कृष्टता के लिए डिज़ाइन किया गया है, इसीलिए आपको उस सिस्टम पर ऐसे तेज़ परिणाम मिल रहे हैं।

अपने SQL सर्वर के लिए, आप sysinos_db_partition_stats DMV से क्वेरी करके पंक्ति गणना को बहुत तेज़ कर सकते हैं।

SELECT s.name AS [Schema], o.name AS [Table], SUM(p.row_count) AS [RowCount]
FROM sys.dm_db_partition_stats p JOIN sys.objects o
ON p.object_id = o.object_id JOIN sys.schemas s
ON o.schema_id = s.schema_id
WHERE p.index_id < 2
AND o.object_id = object_id('MyTable')
GROUP BY o.name, s.name;

एक उच्च लेनदेन के माहौल में, यह DMV 100% सटीक होने की गारंटी नहीं है। लेकिन आपके प्रश्न से, ऐसा लगता है कि आप अपने प्रवास के बाद प्रत्येक तालिका को सत्यापित करने के लिए पंक्ति गणना कर रहे हैं, इसलिए यह प्रश्न आपके लिए काम करना चाहिए।


4
@ क्यों? यदि आप तालिकाओं के माध्यम से लूप करते हैं और प्रत्येक से एक महंगी SELECT COUNT (*) करते हैं - आपके द्वारा अंतिम तालिका में पहुंचने के बाद पहला परिणाम कितना सही है?
हारून बर्ट्रेंड

1
स्पष्टता के लिए, फिल ने कहा था: "डेटा शब्दकोश का उपयोग करना, जो 100% सटीक परिणाम प्रदान नहीं करता है, बुरी सलाह है। मेरी राय में सुझाव को हटाने के लिए या तो जवाब संपादित किया जाना चाहिए या हटा दिया जाना चाहिए - ऐसे उत्तरों के लिए लोगों को Google याद रखें और नेत्रहीन रूप से याद करेंगे। कट और पेस्ट ... "मैं सहमत हूं कि अस्वीकरण महत्वपूर्ण है (और कथित तौर पर कुछ किनारे मामले हैं जहां मेटाडेटा समझदार परिणाम नहीं लौटाता है), मैं असहमत हूं कि मेटाडेटा के विचारों का सामान्य रूप से उपयोग करना बुरी सलाह है।
हारून बर्ट्रेंड

5

यहां एक SQL सर्वर समाधान है जो COUNT_BIGएक अनुक्रमित दृश्य के अंदर उपयोग करता है। यह आपको बड़ी तालिका या अनुक्रमणिका स्कैन के ओवरहेड के बिना और बाद के लिए आवश्यक भंडारण की आवश्यकता के बिना एक ट्रांजेक्शनल-सुसंगत गणना मिलेगी:

CREATE TABLE [dbo].[MyTable](id int);
GO

CREATE VIEW [dbo].[MyTableRowCount]
    WITH SCHEMABINDING
AS

    SELECT
        COUNT_BIG(*) AS TableRowCount
        FROM [dbo].[MyTable];
GO

CREATE UNIQUE CLUSTERED INDEX IX_MyTableRowCount
    ON [dbo].[MyTableRowCount](TableRowCount);
GO

SELECT
    TableRowCount
    FROM [dbo].[MyTableRowCount] WITH(NOEXPAND);

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


@ SQLKiwi: कैसे पढ़े जाते हैं पूर्व-2012 को अवरुद्ध किया जाता है? SQL सर्वर बग?
जॉन सीगल

@JonSeigel - मेरा $ 0,05: सामान्य रूप से बनाए गए सामान्य टेबल पर सामान्य क्लस्टर इंडेक्स टेबल पर एक Sch-M लॉक लागू करता है। एक दृश्य पर, निश्चित रूप से इसकी आवश्यकता नहीं है, लेकिन इसका अर्थ है इंडेक्स व्यू के लिए एक विशेष मामला बनाने के लिए इंडेक्स क्रिएट ऑपरेशन पर बदलाव - जो SQL2012 के लिए किया गया था। IMHO, बिल्कुल।
फैब्रिकियो अरुजो

3

Oracle में, COUNT (*) का उत्तर देने के लिए NOT NULL कॉलम पर एक बाइनरी ट्री इंडेक्स का उपयोग किया जा सकता है। यह FULL TABLE SCAN की तुलना में ज्यादातर मामलों में तेज होगा क्योंकि इंडेक्स आमतौर पर अपने बेस टेबल से छोटे होते हैं।

हालांकि, एक नियमित बाइनरी ट्री इंडेक्स अभी भी 157 मीटर के साथ विशाल होगा। यदि आपकी तालिका समवर्ती (यानी केवल बैच लोड प्रक्रिया) अपडेट नहीं है , तो आप इसके बजाय बिटमैप इंडेक्स का उपयोग करना चाह सकते हैं।

सबसे छोटा बिटमैप इंडेक्स कुछ इस तरह होगा:

CREATE BITMAP INDEX ix ON your_table(NULL);

नल प्रविष्टियों को एक बिटमैप सूचकांक द्वारा ध्यान में रखा जाता है। परिणामी सूचकांक या तो नियमित बाइनरी ट्री इंडेक्स या बेस टेबल की तुलना में छोटे (20-30 8k प्रति मिलियन पंक्ति) होंगे।

परिणामी योजना में निम्नलिखित कार्य प्रदर्शित होने चाहिए:

----------------------------------------------
| Id  | Operation                     | Name | 
----------------------------------------------
|   0 | SELECT STATEMENT              |      |
|   1 |  SORT AGGREGATE               |      |
|   2 |   BITMAP CONVERSION COUNT     |      |
|   3 |    BITMAP INDEX FAST FULL SCAN| IX   |
----------------------------------------------

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


3

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

समानांतर क्वेरी (एंटरप्राइज़ संस्करण आवश्यक) सक्षम करने के लिए, आप ऑप्टिमाइज़र संकेत का उपयोग कर सकते हैं:

select /*+ PARALLEL(mytable, 12) */ count(*) from mytable;

या तालिका के सभी प्रश्नों के लिए समानांतर क्वेरी सक्षम करें:

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