2009-08-20 18 views
6

मेरे पास एक MySQL डेटाबेस में एक टेबल है जिसमें से मैं किसी अन्य दिए गए टाइमस्टैंप के निकटतम टाइमस्टैम्प के साथ पंक्ति का चयन करना चाहता हूं।MySQL में निकटतम पूर्णांक को खोजने का सबसे प्रभावी तरीका?

time टाइमस्टैम्प कॉलम (एक पूर्णांक यूनिक्स टाइमस्टैम्प) है। मैंने मनमाने ढंग से 1250710000 चुना है।

इस क्वेरी है कि मैं के साथ आ गया है, और वहाँ यह करने के लिए एक अधिक कुशल तरीका है मैं सोच रहा हूँ:

SELECT *, ABS(time - 1250710000) AS time_dist FROM table 
ORDER BY time_dist ASC LIMIT 1 

इस यह करने के लिए सबसे अच्छा तरीका है?

उत्तर

10

मान लिया जाये कि time अनुक्रमित है, तो आप मुक्त करने के लिए लगभग अगले रिकॉर्ड प्राप्त कर सकते हैं:

SELECT * FROM table WHERE time > 1250710000 ORDER BY time LIMIT 1 

और अगर मैं गलत नहीं हूँ, एक ही पिछले रिकॉर्ड पर लागू करना चाहिए, MySQL सिर्फ पढ़ा जाएगा सूचकांक रिवर्स ऑर्डर में। दोनों के यूनियन का प्रयोग करें, उन्हें डेट डिफ और वॉयला द्वारा ऑर्डर करें! परिणाम यह

SELECT * 
FROM 
(
    (SELECT *, ABS(time - 1250710000) AS time_diff FROM table WHERE time > 1250710000 ORDER BY time ASC LIMIT 1) 
    UNION ALL 
    (SELECT *, ABS(time - 1250710000) AS time_diff FROM table WHERE time < 1250710000 ORDER BY time DESC LIMIT 1) 
) AS tmp 
ORDER BY time_diff 
LIMIT 1 

आदर्श रूप में दिखाई देंगे, यह > और < के बजाय आप एक ही टाइमस्टैम्प साझा करने के रिकॉर्ड के लिए खाते >= और <= का उपयोग करें और अपनी प्राथमिक आईडी का उपयोग कर संदर्भ रिकॉर्ड को बाहर रखना चाहिए।

+0

अरे! मैं बस लगभग बिल्कुल टाइप कर रहा था! – NickZoic

+0

ग्रेट विचार, लेकिन संदर्भ टाइमस्टैम्प (इस मामले में '1250710000') एक ही तालिका में नहीं है। ऐसा कहकर, मुझे लगता है कि यह क्वेरी दक्षता के मामले में समान है? – heyitsme

+0

** @ cyouung: ** यह क्वेरी दक्षता के मामले में समान नहीं है। आपकी क्वेरी प्रत्येक एबी * पर * एबीएस (समय - 125071000) 'करती है। जब तक आपके पास 'समय' पर एक अनुक्रमणिका हो, तब तक यह क्वेरी दो पंक्तियों से अधिक कभी नहीं पढ़ेगी। –

1

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

SELECT *, ABS(time - 1250710000) AS time_dist FROM table 
WHERE time between(1250610000,1250810000) 
ORDER BY time_dist ASC LIMIT 1 

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

+0

मुझे इस तरह मनमाने ढंग से सीमाएं पसंद नहीं हैं। –

1

क्या यह बड़ा समय और अधिकतम छोटा होने का चयन करने के लिए अधिक कुशल होगा, तो बस उन दोनों को अनुपस्थित करें। इसे संपूर्ण तालिका पर काम करने से बचना चाहिए।

चयन करें MAX (समय) जैसा कि पिछला है < 1250710000;

चयन MIN (समय) अगले समय के रूप में समय> 1250710000;

चयन MIN (एबीएस (पिछला), एबीएस (अगला));

मेरा एसक्यूएल उनको गठबंधन करने के लिए पर्याप्त मजबूत नहीं है, और तीन प्रश्नों के ऊपरी हिस्से में कोई बचत हो सकती है, लेकिन यह संभव हो सकता है।

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

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