2010-12-02 19 views
5

निम्न क्वेरी पर विचार से बचने के लिए:एक SQL क्वेरी अनुकूलन पूर्ण तालिका स्कैन

SELECT * FROM Transactions 
WHERE day(Stamp - interval 3 hour) = 1; 

लेनदेन तालिका में स्टाम्प स्तंभ एक टाइमस्टैम्प है और वहाँ इस पर एक सूचकांक है। मैं इस क्वेरी को कैसे बदल सकता हूं ताकि यह पूर्ण तालिका स्कैन से बचा जा सके?

धन्यवाद (कि का उपयोग कर स्टाम्प बाहर दिन के() समारोह, है)!

+0

मैं "फ़ंक्शन इंडेक्स" के लिए नहीं पूछ रहा हूं - वे मौजूद नहीं हैं। इसके बजाय मैं इस क्वेरी को उसी तरह बदलना चाहता हूं जैसे आप "चयन * तालिका से जहां" sqrt (कॉलम) = 2 "को" तालिका से चुनें * तालिका में बदल सकते हैं जहां कॉलम = 4 " – emx

उत्तर

7

यह कैसे मैं यह कर देगी: वर्ष, माह, दिन या यहाँ तक कि घंटा, मिनट यातायात आप उम्मीद पर निर्भर करता है:

कुछ अतिरिक्त फ़ील्ड जोड़ने। फिर अतिरिक्त फ़ील्ड को पॉप्युलेट करने के लिए एक ट्रिगर बनाएं, शायद अग्रिम में 3 घंटे अंतराल घटाएं। अंत में अतिरिक्त फ़ील्ड पर कुछ अनुक्रमणिका बनाएं।

+0

धन्यवाद, कोई विकल्प नहीं। – emx

+4

MySQL फ़ंक्शन इंडेक्स का समर्थन नहीं करता है - मासिमोग का समाधान प्रत्येक संभावित तिथि सीमा निर्दिष्ट करने का एकमात्र विकल्प है - हालांकि आपकी क्वेरी शायद पंक्तियों के 1/30 वें निकालने जा रही है, इंडेक्स लुकअप का उपयोग करने से काफी तेज़ नहीं होगा पूर्ण टेबल स्कैन। – symcbean

+0

आप प्रदर्शन विचार पर सही हो सकते हैं - वास्तव में इसके बारे में कभी नहीं सोचा। मेरी क्वेरी को बदलने में अधिक दिलचस्पी है। – emx

1

लक्ष्य सिर्फ पूर्ण तालिका स्कैन से बचने के लिए है और आप लेन-देन के लिए प्राथमिक कुंजी (पी नामित कहते हैं) है, तो कवर करना चाहिए जोड़ने सूचकांक

ALTER TABLE Transactions ADD INDEX cover_1 (PK, Stamp) 

फिर

SELECT * FROM Transactions WHERE PK IN (SELECT PK FROM Transactions 
WHERE day(Stamp - interval 3 hour) = 1 
) 

इस क्वेरी पर विचार पूर्ण तालिका स्कैन का उपयोग न करें (हालांकि ऑप्टिमाइज़र पूर्ण स्कैन का उपयोग करने का निर्णय ले सकता है, यदि तालिका में पंक्तियों की संख्या छोटी है या जो भी अन्य सांख्यिकीय कारण है :))

बेहतर तरीका मा y subquery के बजाय अस्थायी तालिका का उपयोग करना है। इससे पहले कि आप अपने मुख्य क्वेरी चलाने

0

अलग से अपने वांछित स्टाम्प मान की गणना करें, यानी

चरण 1 - वांछित स्टाम्प मूल्य की गणना

चरण 2 - क्वेरी चलाने जहां टिकट> (गणना मूल्य)

क्योंकि चरण 2 में कोई गणना नहीं है, तो आप अपनी अनुक्रमणिका का उपयोग करने में सक्षम होना चाहिए।

+0

मैं भी चाहता हूं, लेकिन यह काम नहीं करता है – ajreal

1

आप अक्सर फ़ंक्शन को फिर से लिख सकते हैं ताकि आपके पास WHERE Stamp=XXXX और XXXX जैसा कुछ अभिव्यक्ति हो। आप प्रत्येक महीने, WHERE Stamp BETWEEN timestamp('2010-01-01 00:00:00') AND timestamp ('2010-01-01 23:59:59') OR Stamp BETWEEN ... के लिए बेटवेन स्टेटमेंट की श्रृंखला बना सकते हैं, लेकिन मुझे यकीन नहीं है कि यह इस मामले में इंडेक्स का उपयोग करेगा। मैं एक कॉलम बनाना चाहता था जो महीने के दिन था जब @petr सुझाव देता है।

0

यदि मैं इसे सही ढंग से समझता हूं, तो आप मूल रूप से उन सभी पंक्तियों को वापस करना चाहते हैं जहां प्रत्येक माह में टिकट पहली बार गिरता है (3 घंटे घटाया जाता है)? यदि (और यह एक बड़ा है तो), आपके पास नवीनतम 6 महीने का एक निश्चित विंडो है, आप केवल 6 रेंज परीक्षणों का अनुमान लगा सकते हैं। लेकिन फिर भी, मुझे यकीन नहीं है कि अनुक्रमित पहुंच वैसे भी तेज होगी।

select * 
    from transactions 
where stamp between timestamp '2010-06-01 03:00:00' and timestamp '2010-06-02 02:59:59' 
    or stamp between timestamp '2010-07-01 03:00:00' and timestamp '2010-07-02 02:59:59' 
    or stamp between timestamp '2010-08-01 03:00:00' and timestamp '2010-08-02 02:59:59' 
    or stamp between timestamp '2010-09-01 03:00:00' and timestamp '2010-09-02 02:59:59' 
    or stamp between timestamp '2010-10-01 03:00:00' and timestamp '2010-10-02 02:59:59' 
    or stamp between timestamp '2010-11-01 03:00:00' and timestamp '2010-11-02 02:59:59' 
    or stamp between timestamp '2010-12-01 03:00:00' and timestamp '2010-12-02 02:59:59'; 

एनबी! मुझे यकीन नहीं है कि टाइमस्टैम्प का मिलीसेकंड हिस्सा कैसे काम करता है। आपको तदनुसार इसे पैड करने की आवश्यकता हो सकती है।

0

आईएन क्लॉज से बचने के लिए पेटी के जवाब को थोड़ा सा काम करना, और इसे माईसाम या इनो डीबी के लिए बनाना।

MyISAM लिए

ALTER TABLE Transactions ADD INDEX cover_1 (PK, Stamp) 

या, केवल InnoDB, जहां पी परोक्ष हर सूचकांक में शामिल किया गया है, के लिए

ALTER TABLE Transactions ADD INDEX Stamp (Stamp) 
फिर

SELECT * 
FROM Transactions LEFT JOIN 
    (
    SELECT PK 
    FROM Transactions 
    WHERE DAYOFMONTH(Stamp - interval 3 hour) = 1 
) a ON Transactions.PK=a.PK 

सबक्वेरी एक सूचकांक होगा निष्पादन, और बाहरी क्वेरी केवल पंक्तियों से पंक्तियों को खींचती है जहां एक.पीके आया था।

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