2012-02-17 7 views
5

मैं इस तरह एक MySQL-टेबल आ रही है इस तरह का सूचकांक दो तारीख को स्तंभों में:कैसे क्वेरी

CREATE TABLE `dates` (
`id` int UNSIGNED NULL AUTO_INCREMENT , 
`object_id` int UNSIGNED NOT NULL , 
`date_from` date NOT NULL , 
`date_to` date NULL , 
`time_from` time NULL , 
`time_to` time NULL , 
PRIMARY KEY (`id`) 
); 

जो ज्यादातर इस तरह से क्वेरी की जाती है:

SELECT object_id FROM `dates` 
WHERE NOW() BETWEEN date_from AND date_to 

मैं कैसे सूचकांक करना टेबल सबसे अच्छा है? क्या मुझे दो इंडेक्स बनाना चाहिए, date_from और date_to के लिए एक या दोनों कॉलम पर एक संयुक्त सूचकांक बेहतर है?

+0

मुझे लगता है date_from बजाय सूचकांक बनाने के लिए संयुक्त –

+0

आप [शायद] गलत लग रहा है बेहतर है। कहें कि कुछ वस्तु के लिए 10 पंक्तियां हैं। 8 में अतीत में समाप्ति तिथि है, 1 "वर्तमान" है, और 1 "भविष्य" है। उनमें से कितने "अब()> date_from" (उत्तर: केवल एक) द्वारा फ़िल्टर किए जाते हैं और कितने लोग "अब()

उत्तर

4

प्रश्न के लिए:

WHERE NOW() >= date_from 
    AND NOW() <= date_to 

एक यौगिक सूचकांक (date_from, date_to) बेकार है।

दोनों इंडेक्स बनाएं: (date_from) और (date_to) और SQL ऑप्टिमाइज़र प्रत्येक बार उपयोग करने का निर्णय लेने दें। मूल्यों और चयनकता के आधार पर, अनुकूलक एक या अन्य अनुक्रमणिका चुन सकता है। या उनमें से कोई भी नहीं। एक इंडेक्स बनाने का कोई आसान तरीका नहीं है जो दोनों स्थितियों को ध्यान में रखेगा।


(एक स्थानिक सूचकांक इस तरह के एक शर्त अनुकूलन करने के लिए, यदि आप दिनांक उसका अनुवाद कर सकें अक्षांश और देशांतर के लिए इस्तेमाल किया जा सकता है)।

अद्यतन

मेरे गलती। (date_from, date_to, object_id) पर एक सूचकांक वास्तव में इस क्वेरी के लिए कुछ स्थितियों में उपयोग किया जा सकता है और वास्तव में उपयोग किया जा सकता है। यदि NOW() <= date_from की चयनिता काफी अधिक है, तो अनुकूलक तालिका पर एक पूर्ण स्कैन करने या अन्य अनुक्रमणिका का उपयोग करने से, इस अनुक्रमणिका का उपयोग करने का विकल्प चुनता है। ऐसा इसलिए है क्योंकि यह एक कवरिंग इंडेक्स है, जिसका अर्थ है कि तालिका से प्राप्त करने के लिए कोई डेटा आवश्यक नहीं है, केवल इंडेक्स डेटा से पढ़ना आवश्यक है।

मामूली नोट (प्रदर्शन से संबंधित नहीं, केवल क्वेरी की शुद्धता)। जबकि CURRENT_DATE() एक DATE देता है, समय हिस्सा बिना

WHERE CURRENT_DATE() >= date_from 
    AND CURRENT_DATE() <= date_to 

NOW() फ़ंक्शन एक DATETIME,: यदि आप इस चाहते

WHERE CURRENT_DATE() >= date_from 
    AND (CURRENT_DATE() + INTERVAL 1 DAY <= date_to 
     OR (CURRENT_DATE() = NOW() 
     AND CURRENT_DATE() = date_to 
      ) 
    ) 

क्या आप वाकई कि चाहते हैं या कर रहे हैं: अपने हालत बराबर है करने के लिए।

+0

आपके उत्तर के लिए धन्यवाद - असल में मेरे पास दो प्रकार की क्वेरी है: या तो मैं अपनी ऑब्जेक्ट के लिए सभी संबंधित तिथियां प्राप्त करने के लिए या ऑब्जेक्ट_आईडी द्वारा चयन कर रहा हूं, एक तिथि सीमा चुनकर जहां एक चयनित दिन (चाहे वह 'अब()' हो या कोई अन्य तारीख) 'date_from' और' date_to' के बीच है, इसलिए मुझे उस दिन होने वाली सभी पंक्तियां मिलती हैं। – acme

0

(date_from, date_to) है कि एक सूचकांक के रूप में के साथ एक सूचकांक बनाएं जहां मापदंड

के लिए प्रयोग करने योग्य होगा आप अलग अनुक्रमणिका बनाते हैं तो संभव MySQL एक या दोनों

1

के बजाय अन्य का उपयोग करना होगा आपकी तालिका के आकार के संबंध में कितनी पंक्तियां आपकी क्वेरी लौटती हैं? यदि यह 10 प्रतिशत से अधिक है तो मैं एक इंडेक्स बनाने के लिए परेशान नहीं होगा, इस तरह के मामले में आप टेबल टेबल के करीब भी वैसे भी स्कैन करते हैं। यदि यह 10 प्रतिशत से कम है, तो इस मामले में, (date_from, date_to, object_id) conteing इंडेक्स का उपयोग करेगा, ताकि क्वेरी परिणाम पूरी तरह से इंडेक्स में जानकारी से बनाया जा सके, डेटाबेस को वापस ट्रैक करने के लिए object_id के मान प्राप्त करने के लिए तालिका डेटा।

आपकी तालिका के आकार के आधार पर यह बहुत सारी जगह का उपयोग कर सकता है। यदि आप इसे छोड़ सकते हैं, तो इसे आज़माएं।

+0

मुझे नहीं पता था कि चयनित फ़ील्ड को इंडेक्स से लिया गया है, जानना अच्छा है! मुझे लगता है कि पंक्ति गणना पांच अंक है और मैच 10 प्रतिशत से कम हैं। तो यह जाने का रास्ता लगता है। – acme

2

आपको ypercube द्वारा समझाए गए दिनांक_from, date_to और object_id को कवर करने वाली एक अनुक्रमणिका बनाना चाहिए। इंडेक्स में फ़ील्ड का ऑर्डर इस बात पर निर्भर करता है कि आपके पास अतीत या भविष्य के लिए अधिक डेटा होगा या नहीं। जैसा कि संजय की टिप्पणी के जवाब में इरविन द्वारा इंगित किया गया है, यदि आपके पास अतीत में और इसके विपरीत अधिक तिथियां हैं तो date_to फ़ील्ड अधिक चुनिंदा होगा।

CREATE INDEX ON (date_to, date_from, object_id); 
+0

ठीक है, इसे इंगित करने के लिए धन्यवाद! – acme