2012-01-24 11 views
25

मुझे SQL तालिका में एक बड़ी संख्या में एक SELECT COUNT (*) के साथ एक प्रदर्शन समस्या है।SQLite: बड़ी तालिकाओं पर COUNT धीमी

जैसा कि मुझे अभी तक उपयोग करने योग्य उत्तर नहीं मिला है और मैंने कुछ और परीक्षण किया है, मैंने अपने नए निष्कर्षों को शामिल करने के लिए अपना प्रश्न संपादित किया।

2 टेबल है:

CREATE TABLE Table1 (
Key INTEGER NOT NULL, 
... several other fields ..., 
Status CHAR(1) NOT NULL, 
Selection VARCHAR NULL, 
CONSTRAINT PK_Table1 PRIMARY KEY (Key ASC)) 

CREATE Table2 (
Key INTEGER NOT NULL, 
Key2 INTEGER NOT NULL, 
... a few other fields ..., 
CONSTRAINT PK_Table2 PRIMARY KEY (Key ASC, Key2 ASC)) 

Table1 लगभग 8 मिलियन रिकॉर्ड है और तालिका 2 लगभग 51 मिलियन रिकॉर्ड है, और databasefile 5GB खत्म हो गया है।

CREATE INDEX IDX_Table1_Status ON Table1 (Status ASC, Key ASC) 
CREATE INDEX IDX_Table1_Selection ON Table1 (Selection ASC, Key ASC) 

"स्थिति" की आवश्यकता है क्षेत्र केवल 6 अलग-अलग मान, "चयन" की आवश्यकता नहीं है, लेकिन है और केवल लगभग 15 लाख मूल्यों बातिल और केवल चारों ओर से अलग है:

Table1 2 अधिक अनुक्रमित है 600k विशिष्ट मूल्य।

मैंने दोनों टेबलों पर कुछ परीक्षण किए हैं, आप नीचे दिए गए समय देख सकते हैं, और मैंने प्रत्येक अनुरोध (क्यूपी) के लिए "क्वेरी प्लान समझाया" जोड़ा। मैंने डेटाबेस फ़ाइल को यूएसबी-मेमोरीस्टिक पर रखा ताकि मैं प्रत्येक टेस्ट के बाद इसे हटा सकूं और डिस्क कैश के हस्तक्षेप के बिना विश्वसनीय परिणाम प्राप्त कर सकूं। यूएसबी पर कुछ अनुरोध तेज हैं (मुझे लगता है कि तलाश समय की कमी के कारण), लेकिन कुछ धीमे (टेबल स्कैन) हैं।

SELECT COUNT(*) FROM Table1 
    Time: 105 sec 
    QP: SCAN TABLE Table1 USING COVERING INDEX IDX_Table1_Selection(~1000000 rows) 
SELECT COUNT(Key) FROM Table1 
    Time: 153 sec 
    QP: SCAN TABLE Table1 (~1000000 rows) 
SELECT * FROM Table1 WHERE Key = 5123456 
    Time: 5 ms 
    QP: SEARCH TABLE Table1 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows) 
SELECT * FROM Table1 WHERE Status = 73 AND Key > 5123456 LIMIT 1 
    Time: 16 sec 
    QP: SEARCH TABLE Table1 USING INDEX IDX_Table1_Status (Status=?) (~3 rows) 
SELECT * FROM Table1 WHERE Selection = 'SomeValue' AND Key > 5123456 LIMIT 1 
    Time: 9 ms 
    QP: SEARCH TABLE Table1 USING INDEX IDX_Table1_Selection (Selection=?) (~3 rows) 

आप देख सकते हैं मायने रखता है बहुत धीमी गति से कर रहे हैं, लेकिन सामान्य चयन तेजी से (2 है, जो 16 सेकंड लगे को छोड़कर) कर रहे हैं।

एक ही तालिका 2 के लिए चला जाता है:

SELECT COUNT(*) FROM Table2 
    Time: 528 sec 
    QP: SCAN TABLE Table2 USING COVERING INDEX sqlite_autoindex_Table2_1(~1000000 rows) 
SELECT COUNT(Key) FROM Table2 
    Time: 249 sec 
    QP: SCAN TABLE Table2 (~1000000 rows) 
SELECT * FROM Table2 WHERE Key = 5123456 AND Key2 = 0 
    Time: 7 ms 
    QP: SEARCH TABLE Table2 USING INDEX sqlite_autoindex_Table2_1 (Key=? AND Key2=?) (~1 rows) 

क्यों SQLite Table1 पर प्राथमिक कुंजी पर स्वचालित रूप से बनाया सूचकांक का उपयोग नहीं कर रहा है? और क्यों, जब वह तालिका 2 पर ऑटो-इंडेक्स का उपयोग करता है, तो इसमें अभी भी बहुत समय लगता है?

मैंने SQL Server 2008 R2 पर समान सामग्री और अनुक्रमणिका के साथ एक ही सारणी बनाई और वहां गणना लगभग तात्कालिक हैं।

नीचे दी गई टिप्पणियों में से एक डेटाबेस पर विश्लेषण निष्पादित करने का सुझाव दिया गया है। मैंने किया और इसे पूरा होने में 11 मिनट लग गए। उसके बाद, मैं परीक्षण के कुछ फिर से भाग:

SELECT COUNT(*) FROM Table1 
    Time: 104 sec 
    QP: SCAN TABLE Table1 USING COVERING INDEX IDX_Table1_Selection(~7848023 rows) 
SELECT COUNT(Key) FROM Table1 
    Time: 151 sec 
    QP: SCAN TABLE Table1 (~7848023 rows) 
SELECT * FROM Table1 WHERE Status = 73 AND Key > 5123456 LIMIT 1 
    Time: 5 ms 
    QP: SEARCH TABLE Table1 USING INTEGER PRIMARY KEY (rowid>?) (~196200 rows) 
SELECT COUNT(*) FROM Table2 
    Time: 529 sec 
    QP: SCAN TABLE Table2 USING COVERING INDEX sqlite_autoindex_Table2_1(~51152542 rows) 
SELECT COUNT(Key) FROM Table2 
    Time: 249 sec 
    QP: SCAN TABLE Table2 (~51152542 rows) 

आप देख सकते हैं, प्रश्नों एक ही समय लिया (क्वेरी योजना को छोड़कर अब पंक्तियों की वास्तविक संख्या को दिखा रहा है), केवल धीमी चयन है अब भी तेज़

अगला, मैं तालिका 1 के मुख्य क्षेत्र पर डैन अतिरिक्त अनुक्रमणिका बना देता हूं, जो ऑटो-इंडेक्स से मेल खाना चाहिए। मैंने विश्लेषण डेटा के बिना मूल डेटाबेस पर किया था। इस इंडेक्स को बनाने में 23 मिनट लग गए (याद रखें, यह यूएसबी-स्टिक पर है)।

CREATE INDEX IDX_Table1_Key ON Table1 (Key ASC) 

तब मैं परीक्षण फिर से भाग:

SELECT COUNT(*) FROM Table1 
    Time: 4 sec 
    QP: SCAN TABLE Table1 USING COVERING INDEX IDX_Table1_Key(~1000000 rows) 
SELECT COUNT(Key) FROM Table1 
    Time: 167 sec 
    QP: SCAN TABLE Table2 (~1000000 rows) 
SELECT * FROM Table1 WHERE Status = 73 AND Key > 5123456 LIMIT 1 
    Time: 17 sec 
    QP: SEARCH TABLE Table1 USING INDEX IDX_Table1_Status (Status=?) (~3 rows) 

आप देख सकते हैं, सूचकांक गिनती (*) से मदद की, लेकिन गिनती (कुंजी) के साथ नहीं।

CREATE TABLE Table1 (
Key INTEGER PRIMARY KEY ASC NOT NULL, 
... several other fields ..., 
Status CHAR(1) NOT NULL, 
Selection VARCHAR NULL) 

तब मैं परीक्षण फिर से भाग:

SELECT COUNT(*) FROM Table1 
    Time: 6 sec 
    QP: SCAN TABLE Table1 USING COVERING INDEX IDX_Table1_Selection(~1000000 rows) 
SELECT COUNT(Key) FROM Table1 
    Time: 28 sec 
    QP: SCAN TABLE Table1 (~1000000 rows) 
SELECT * FROM Table1 WHERE Status = 73 AND Key > 5123456 LIMIT 1 
    Time: 10 sec 
    QP: SEARCH TABLE Table1 USING INDEX IDX_Table1_Status (Status=?) (~3 rows) 

हालांकि क्वेरी योजना, एक ही हैं

अंत में, मैं मेज के बजाय एक स्तंभ बाधा का उपयोग कर एक मेज बाधा के बनाया समय बहुत बेहतर हैं। ऐसा क्यों है ?

समस्या यह है कि वैकल्पिक तालिका मौजूदा तालिका को कनवर्ट करने की अनुमति नहीं देती है और मेरे पास बहुत सारे मौजूदा डेटाबेस हैं जिन्हें मैं इस फ़ॉर्म में परिवर्तित नहीं कर सकता। इसके अलावा, टेबल बाधा के बजाय कॉलम contraint का उपयोग तालिका 2 के लिए काम नहीं करेगा।

क्या किसी को कोई विचार है कि मैं क्या गलत कर रहा हूं और इस समस्या को कैसे हल किया जाए?

मैंने टेबल बनाने के लिए System.Data.SQLite संस्करण 1.0.74.0 का उपयोग किया और परीक्षण चलाने के लिए मैंने SQLiteSpy 1.9.1 का उपयोग किया।

धन्यवाद,

मार्क

+4

यदि आपके पास SQLite के साथ प्रदर्शन समस्याएं हैं, तो समाधान आमतौर पर एक बड़े डीबी सर्वर पर जाने के लिए होता है (मैं एमएस एसक्यूएल पर पोस्टग्रेस की अनुशंसा करता हूं)। – Borealid

+0

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

+0

जो वास्तव में डरावना है, क्योंकि (कम से कम डीबी 2 के लिए) अधिकांश आरडीबीएमएस शायद प्रभावी रूप से कैश की गई जानकारी का उपयोग करते हैं - यदि आप _all_ पंक्तियों (या किसी इंडेक्स में किसी चीज़ द्वारा प्रतिबंधित) की गणना के लिए पूछते हैं, तो यह आमतौर पर उस जानकारी को पढ़ सकता है सूचकांक स्वयं - सूचकांक प्रविष्टियों की संख्या जानता है। यह दोगुना डरावना है कि आप कहते हैं कि अन्य सभी 'चयन' तेज़ हैं - उन्हें सही मायने में अनुकूलित करने में सक्षम होने के लिए रिकॉर्ड गणना की आवश्यकता है! जब तक कुछ डरावना नहीं हो रहा है, और आप तालिका को लॉक कर रहे हैं (दोहराने योग्य पढ़ने का लेनदेन स्तर, या कुछ ऐसे?) ... –

उत्तर

1

यह बहुत मदद नहीं कर सकते हैं, लेकिन आप अपने डेटाबेस के बारे में आंकड़े के पुनर्निर्माण के लिए ANALYZE आदेश चला सकते हैं। पूरे डेटाबेस के आंकड़ों के पुनर्निर्माण के लिए "ANALYZE;" चलाने का प्रयास करें, फिर अपनी क्वेरी दोबारा चलाएं और देखें कि यह कोई तेज़ है या नहीं।

+0

मैंने एनालिज कमांड को निष्पादित किया, इसे पूरा करने में काफी समय लगा, लेकिन परिणाम न बदल गया, गिनती अभी भी धीमी थी। – Marc

+0

'विश्लेषण' ने 'डीईएफटी जॉइन' –

0

कॉलम बाधा के मामले में, SQLite मानचित्र कॉलम जो आंतरिक पंक्ति आईडी (जो बदले में कई आंतरिक अनुकूलन स्वीकार करता है) में INTEGER PRIMARY KEY घोषित किया जाता है। सैद्धांतिक रूप से, यह अलग-अलग घोषित प्राथमिक कुंजी बाधा के लिए भी ऐसा ही कर सकता है, लेकिन ऐसा लगता है कि कम से कम SQLite के उपयोग के साथ अभ्यास में ऐसा नहीं करना प्रतीत होता है। (System.Data.SQLite 1.0.74.0 कोर SQLite 3.7.7.1 से मेल खाता है। हो सकता है कि आप 1.0.7 9.0 के साथ अपने आंकड़ों को फिर से जांचना चाहें; आपको ऐसा करने के लिए अपना डेटाबेस बदलने की आवश्यकता नहीं है, केवल लाइब्रेरी।)

+0

करते समय मेरे डीबी के लिए इस मुद्दे को ठीक किया है, मैंने System.Data.SQlite (1.0.79.0) और I के नवीनतम संस्करण के साथ दोनों प्रश्नों (गिनती (*) और गिनती (कुंजी)) की कोशिश की है। पहले के रूप में एक ही परिणाम प्राप्त किया। – Marc

+0

जैसा कि मुझे थोड़ा परीक्षण कार्यक्रम लिखना पड़ा था (क्योंकि SQLIteSpy SQLite के पुराने संस्करण का उपयोग करता है, 3.7.8), मैंने इसे 32 और 64 बिट्स में दोनों की कोशिश की, लेकिन मैंने दोनों के लिए एक ही परिणाम प्राप्त किए। – Marc

0

तेज प्रश्नों के लिए आउटपुट सभी "क्यूपी: खोज" टेक्स्ट से शुरू होता है। जबकि धीमे प्रश्नों के लिए उन लोगों को "क्यूपी: एससीएएन" पाठ से शुरू होता है, जो बताता है कि वर्ग उत्पन्न करने के लिए स्क्लाइट पूरी तालिका का स्कैन कर रहा है।

"स्क्लाइट टेबल स्कैन गिनती" के लिए गुगलिंग the following पाता है, जो बताता है कि गिनती पुनर्प्राप्त करने के लिए एक पूर्ण टेबल स्कैन का उपयोग करना ही स्क्लाइट काम करता है, और इसलिए संभवतः अपरिहार्य है।

एक कामकाज के रूप में, और उस स्थिति के बाद केवल आठ मान हैं, मुझे आश्चर्य हुआ कि क्या आप निम्न की तरह एक क्वेरी का उपयोग करके जल्दी से गिनती प्राप्त कर सकते हैं?

1 का चयन करें जहां स्थिति = 1 संघ 1 चयन जहां स्थिति = 2 ...

तो परिणाम में पंक्तियों गिनती। यह स्पष्ट रूप से बदसूरत है, लेकिन यह काम कर सकता है अगर यह स्कैन के बजाए क्वेरी को चलाने के लिए एसक्लाइट को राजी करता है। प्रत्येक बार "1" लौटने का विचार वास्तविक डेटा लौटने के ओवरहेड से बचने के लिए है।

+0

मुझे पहले से ही यह [पोस्ट] (http://www.mail-archive.com/[email protected]/msg10279.html) SQLite के लेखक से मिला है, इसलिए मैंने पहले ही आशा छोड़ दी है, क्योंकि ट्रिगर्स जोड़ना होगा आवेषण और हटावट पर भी दंडित होना। लेकिन मैंने आपके सुझाव की कोशिश की। मैंने पहली बार टेबल 1 से 'SELECT COUNT (*) की कोशिश की जहां स्थिति (1,2,3,4,5,6) ', जिसमें 86 सेकेंड (थोड़ा तेज) में निष्पादित किया गया, क्यूपी:' खोज तालिका तालिका 1 का उपयोग इंडेक्स IDX_Table1_Status (स्थिति =?) (~ 60 पंक्तियां); सटीक सूची सबकुछ 1'। बेहतर लेकिन पर्याप्त अच्छा नहीं है। – Marc

+0

मैंने आपके संघ के सुझाव की कोशिश की। 'से COUNT (*) चुनें (तालिका 1 से 1 चुनें जहां स्थिति = 1 यूनियन तालिका 1 से चुनें 1 स्थिति = 2 यूनियन ...)' 1 लौटा, एसयूएम (*) के लिए, मुझे लगता है कि विशेषताओं के कारण संघ। 'से COUNT (*) चुनें (तालिका 1 से 1 चुनें जहां स्थिति = 1 यूनियन तालिका 1 से चुनें 2 स्थिति = 2 यूनियन ...)' वापस लौटा। तो फिनली मैंने कोशिश की 'COUNT (*) से चुनें (तालिका 1 से चयन करें जहां स्थिति = 1 यूनियन तालिका 1 से चुनें कुंजी जहां स्थिति = 2 यूनियन ...) 'जो सही परिणाम लौटा, लेकिन बहुत धीमी (116 सेकंड)। फिर भी सुझाव के लिए धन्यवाद। – Marc

+0

और मेरी पहली कोशिश (तालिका 1 से चुनें COUNT (*) जहां स्थिति (1,2,3,4,5,6) ') जो थोड़ा बेहतर था, मेरी दूसरी तालिका (तालिका 2) के लिए काम नहीं करेगी। – Marc

0

क्वेरी प्रदर्शन में सुधार करने के लिए यहां एक संभावित कार्यवाही है। संदर्भ से, ऐसा लगता है जैसे आपकी क्वेरी में ढाई मिनट लगते हैं।

मान लें कि आपके पास डेट_क्रेटेड कॉलम है (या एक जोड़ सकता है), प्रत्येक दिन आधी रात को पृष्ठभूमि में एक क्वेरी चलाएं (कहें 00:05 बजे) और पिछली_अपडेटेड तिथि के साथ कहीं भी मूल्य को जारी रखें (I ' थोड़ा सा वापस आ जाएगा)।

फिर, अपने डेट_क्रेटेड कॉलम (इंडेक्स के साथ) के विरुद्ध चलना, आप तालिका से SELECT COUNT (*) जैसी क्वेरी करके पूर्ण तालिका स्कैन से बच सकते हैं दिनांक_अपडेटेड> "[TODAY] 00:00:05"।

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

एकमात्र पकड़ यह है कि 12:05 पूर्वाह्न से 12:07 बजे तक (जिस अवधि के दौरान आपकी कुल गणना क्वेरी चल रही है) आपके पास दौड़ की स्थिति है जिसे आप अपनी पूर्ण तालिका स्कैन गिनती() के अंतिम_अपडेटेड मूल्य की जांच कर सकते हैं। यदि यह 24 घंटे पुराना है, तो आपकी वृद्धिशील गिनती क्वेरी को पूरे दिन की गणना और समय बीतने की आवश्यकता है। यदि यह < 24 घंटे पुराना है, तो आपकी वृद्धिशील गणना क्वेरी को आंशिक दिन की गणना खींचने की आवश्यकता है (केवल आज समय बीत चुका है)।

+0

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

18

http://old.nabble.com/count(*)-slow-td869876.html

SQLite से हमेशा गिनती (*) के लिए एक पूर्ण तालिका स्कैन करता है। यह
इस
प्रक्रिया को गति देने के लिए तालिकाओं पर मेटा जानकारी नहीं रखता है।

मेटा जानकारी नहीं रखना एक जानबूझकर डिजाइन
निर्णय है। यदि प्रत्येक तालिका में गिनती संग्रहित बीटी के प्रत्येक अंक (या बेहतर, प्रत्येक
नोड संग्रहीत किया जाता है) तो
को अद्यतन करने के लिए और अधिक INSERT या DELETE पर होना होगा। यह
सामान्य
मामले में जहां भी गिनती (*) गति महत्वहीन है, INSERT और DELETE को धीमा कर देगी।

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

बेशक

, तो यह आपको
पर निर्भर है की जरूरत है COUNT सेकंड एक पूर्ण पंक्ति संख्या रखे जाने लायक नहीं है जहां खंड (अर्थात जहां फ़ील्ड 1> 0 और field2 < 1000000000)।

+1

देर से उत्तर के लिए खेद है, मैं कुछ दिनों बीमार हूँ। मैंने अपनी टिप्पणियों में से एक में उसी पोस्ट के लिए पहले से ही एक लिंक पोस्ट कर दिया है। मुझे लगता है कि ट्रिगर्स जोड़ना बड़े पैमाने पर आवेषण और हटावट पर दंडित होगा। मुझे लगता है कि यह प्रत्येक डालने के अंत में टेबल गिनती का ट्रैक रखेगा और/या लेनदेन को हटा देगा, इसलिए काउंटर केवल एक बार अपडेट किया जाता है और प्रत्येक सम्मिलित/हटाए जाने पर नहीं। – Marc

+0

इसके अलावा, 'COUNT (1)' 'COUNT (*)' और यहां तक ​​कि 'COUNT (" id ") से भी तेज होना चाहिए। –

+0

@AlixAxel मेरे सभी परीक्षणों में 'COUNT()' और 'COUNT (*)' सबसे तेज़ हैं, 'COUNT (1)' डबल और 'COUNT (ROWID)' समय लेते हुए। – springy76

0

मुझे वही समस्या थी, मेरी स्थिति में VACUUM कमांड ने मदद की। डेटाबेस COUNT (*) की गति पर इसके निष्पादन के बाद 100 गुना वृद्धि हुई। हालांकि, कमांड को अपने डेटाबेस में कुछ मिनटों की आवश्यकता है (20 लाख रिकॉर्ड)। जब मैं मुख्य खिड़की के विनाश के बाद बाहर निकलता हूं, तो मैं VACUUM चलाकर इस समस्या को हल करता हूं, इसलिए देरी उपयोगकर्ता को समस्या नहीं देती है।

+3

में निष्पादित करता है VACUUM पूरी फ़ाइल को पढ़ने और लिखने के लिए मजबूर करेगा, इसलिए यह डिस्क सामग्री को स्मृति कैश में भर देगा। यही कारण है कि यह तेज़ है। अगर आप रीबूट करते हैं आपका पीसी, आपको फिर से धीमा लगेगा, मुझे लगता है। –

18

आप किसी भी रिकॉर्ड, कर d नहीं DELETE है:

SELECT MAX(_ROWID_) FROM "table" LIMIT 1; 

पूर्ण तालिका स्कैन से बचने जाएगा। ध्यान दें कि _ROWID_ is a SQLite identifier

+0

सबसे अच्छा जवाब होना चाहिए। तुरंत लौटता है और एक अच्छा अनुमान (आमतौर पर आप जो चाहते हैं) देता है – easytiger

+1

पुष्टि करते हुए, यह मेरे डीबी के लिए 115 मिलियन के साथ कुछ एमएस के भीतर एक मूल्य देता है एक टेबल में रिकॉर्ड। एक पूर्ण COUNT (*) करना वास्तव में कभी भी शिकायत नहीं करता है eted (मैं 4 घंटे के बाद इंतजार छोड़ दिया)। –

+1

यह अच्छा है लेकिन यह ध्यान में रखें कि एलिक्स ने पहले ही क्या कहा है - भले ही आपने इस तालिका में एक ही रिकॉर्ड हटा दिया हो - भले ही आपको गलत परिणाम मिलेंगे (चूंकि _ROWID_ एक बढ़ती रिकॉर्ड आईडी है, और 'हटाना' होगा _ROWID_ को कम करने का कारण नहीं है)। – strangetimes

2

सितारों की गिनती न करें, रिकॉर्ड गिनें!या दूसरी भाषा में, कभी भी

चुनें COUNT (*) टैबलेटनाम से;

उपयोग

COUNT का चयन करें (ROWID) tablename से;

अंतर देखने के लिए दोनों के लिए EXPLAIN QUERY योजना कॉल करें। सुनिश्चित करें कि आपके पास WHERE खंड में उल्लिखित सभी कॉलम वाले एक इंडेक्स है।

+0

मेरे लिए कोई फर्क नहीं पड़ता। – Fidel

+0

@ फिडेल आपके डेटाबेस मॉडल और सेटिंग्स पर निर्भर करता है। मेरे प्रयोग में, SQLite ने पूर्ण तालिका गणना के लिए ROWID के साथ उपयोग किए जाने पर इंडेक्स खोज के बजाय तारांकन खोज के लिए एक पूर्ण स्कैन किया था। शायद मैंने कुछ और भी अनदेखा किया है, मैं सही होने का दावा नहीं करता हूं। हालांकि, मैं अब भी ** योजना की व्याख्या योजना ** का उपयोग करने की सलाह देते हैं! बस डीबी को पूर्ण स्कैन के बजाय पीके पर इंडेक्स का उपयोग करने के लिए मजबूर करें और ओएस कैशिंग प्रभाव के लिए नीचे देखें अर्नुड टिप्पणियों के रूप में। आपके प्रश्न हमेशा जल्दी हो सकते हैं! – Thinkeye

+1

यह ज्यादातर मामलों में गलत है। कम से कम मेरी सभी टेबलों में रोटीड द्वारा खोजे जाने से 22 सेकंड की दूरी तय होती है, जो 4 सेकेंड की गिनती होती है – easytiger

संबंधित मुद्दे