मेरे पास start_date
और end_date
के साथ DATE
प्रकार के साथ फ़ील्ड के साथ लगभग 100 मिलियन रिकॉर्ड के साथ एक बड़ी तालिका है। मुझे 2013-08-20
और 2013-08-30
के बीच कुछ दिनांक सीमा के साथ ओवरलैप की संख्या की जांच करने की आवश्यकता है, इसलिए मैं इसका उपयोग करता हूं।दिनांक के आधार पर mysql प्रदर्शन
SELECT COUNT(*) FROM myTable WHERE end_date >= '2013-08-20'
AND start_date <= '2013-08-30'
दिनांक कॉलम अनुक्रमित हैं। महत्वपूर्ण बात यह है कि जिस तारीख को मैं ओवरलैप के लिए खोज रहा हूं वह हमेशा भविष्य में है, जबकि तालिका में रिकॉर्ड का मुख्य भाग अतीत में है (97-99 मिलियन के बारे में कहें)। तो, यह प्रश्न अगर मैं एक स्तंभ is_future - TINYINT
जोड़ने के लिए, तेजी से हो जाएगा, इसलिए, केवल इस
SELECT COUNT(*) FROM myTable WHERE is_future = 1
AND end_date >= '2013-08-20' AND start_date <= '2013-08-30'
की तरह है कि हालत की जाँच करके यह बाकी 97 मिलियन या तो रिकॉर्ड को बाहर निकाल देगा और केवल के लिए तारीख हालत की जाँच करेगा शेष 1-3 मिलियन रिकॉर्ड?
मैं उपयोग MySQL
धन्यवाद
संपादित
mysql इंजन InnoDB, MyISAM
यहाँ है, लेकिन काफी फर्क करेगा कि क्या यह कहना है तालिका बनाने
CREATE TABLE `orders` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`title`
`start_date` date DEFAULT NULL,
`end_date` date DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
संपादित 2 @Robert सह के बाद जवाब देने के
विभाजन इस मामले के लिए एक अच्छा विचार की तरह लग रहा है, लेकिन यह मुझे is_future
क्षेत्र जब तक कि मैं प्राथमिक कुंजी के रूप में यह परिभाषित के आधार पर विभाजन बनाने के लिए अनुमति नहीं है, अन्यथा मैं निकाल देना चाहिए मेरी मुख्य प्राथमिक कुंजी - आईडी, जो मैं नहीं कर सकता। इसलिए, यदि मैं उस क्षेत्र को प्राथमिक कुंजी के रूप में परिभाषित करता हूं, तो विभाजन का अर्थ है, अगर मैं is_future
फ़ील्ड द्वारा प्राथमिक कुंजी की खोज करता हूं तो यह पहले से तेज़ नहीं होगा।
संपादित 3 वास्तविक क्वेरी जहां मैं इस उस समय अवधि की कुछ मुक्त टेबल
SELECT r.id, r.name, r.table_count
FROM restaurants r
LEFT JOIN orders o
ON r.id = o.restaurant_id
WHERE o.id IS NULL
OR (r.table_count > (SELECT COUNT(*)
FROM orders o2
WHERE o2.restaurant_id = r.id AND
end_date >= '2013-08-20' AND start_date <= '2013-08-30'
AND o2.status = 1
)
)
समाधान है कि रेस्तरां का चयन करने के लिए है उपयोग करने की आवश्यकता एक बहुत अधिक अनुसंधान और परीक्षण के बाद मेरे मामले में पंक्तियों की संख्या गिनने का सबसे तेज़ तरीका सिर्फ एक और शर्त जोड़ना था, कि start_date वर्तमान दिनांक से अधिक है (क्योंकि खोज के लिए तिथि सीमा हमेशा भविष्य में होती है)
SELECT COUNT(*) FROM myTable WHERE end_date >= '2013-09-01'
AND start_date >= '2013-08-20' AND start_date <= '2013-09-30'
भी एक इंडेक्स होना आवश्यक है - start_date और end_date फ़ील्ड्स के साथ (धन्यवाद @ सिमकबीन)। परिणामस्वरूप 7 सेकंड से 10 मीटर पंक्तियों के साथ तालिका पर निष्पादन समय - 0.050 सेकंड बन गया।
समाधान 2 (@Robert Co) इस मामले में विभाजन भी काम करता है !! - शायद यह अनुक्रमण से बेहतर समाधान है। या वे दोनों एक साथ लागू किया जा सकता है।
धन्यवाद
महान प्रश्न ... इसे आज़माएं और हमें बताएं। ;) आप 'BETWEEN' का उपयोग क्यों नहीं कर रहे हैं? – DevlshOne
@DevlshOne,: डी, इस मामले में कैसे उपयोग करें? मैं 2 कॉलम की तुलना करता हूं, क्या मैं कर सकता हूं? – dav
क्या आप बिल्ड टेबल स्टेटमेंट और स्टोरेज इंजन के बारे में जानकारी पोस्ट कर सकते हैं, यह मायने रखता है .. –