2011-09-17 13 views
8

कल्पना कीजिए कि मेरे पास एक तालिका है जिसमें एक पुस्तक के सभी अध्याय और प्रत्येक अध्याय से प्रारंभ/समाप्ति पृष्ठ शामिल है।इंडेक्स का लाभ उठाने के दौरान मैं दो कॉलम के बीच कैसे क्वेरी कर सकता हूं?

chapter | start_page  | end_page 
-------------------------------------- 
    1 |  1   | 24 
    2 |  25  | 67 
    3 |  68  | 123 
    4 |  124  | 244 
    5 |  245  | 323 

मैं यह जानने का प्रयास कर रहा हूं कि एक यादृच्छिक पृष्ठ किस अध्याय पर पड़ता है, उदाहरण के लिए पेज 215 कहें।

मेरा पहला विचार मेरी मेज के बड़े आकार के कारण इस

SELECT `chapter` 
FROM `book` 
WHERE `start_page` <= 215 
AND `end_page` >= 215 

की तरह एक प्रश्न उपयोग करने के लिए दुर्भाग्य से MySQL ऊपर क्वेरी जो एक बड़ी समस्या यह है में इंडेक्सों का लाभ नहीं उठा पा रहा था।

कुछ शोध करने के बाद मैं इस क्वेरी के साथ आया जो इंडेक्स का लाभ उठाता है।

SELECT `chapter` 
FROM `book` 
WHERE `start_page` <= 215 
ORDER BY `start_page` DESC  
LIMIT 1 

अब मुद्दा यह है कि मैं इंडेक्स का लाभ उठाते समय कई यादृच्छिक पृष्ठों से पूछताछ करने की क्षमता चाहता हूं। ऐसा लगता है कि मैं अपनी आखिरी क्वेरी को संशोधित नहीं कर सकता क्योंकि यह परिणामों को सीमित करने पर बहुत निर्भर है।

कोई सलाह बहुत सराहना की जाएगी!

अद्यतन: रे टोल से एक टिप्पणी के लिए धन्यवाद, मेरे पास एक प्रश्न है जो मुझे आश्चर्यजनक प्रदर्शन के साथ परिणाम देता है।

SELECT chapter 
FROM book 
WHERE (start_page = (SELECT max(start_page) FROM book WHERE start_page <= 73) AND end_page >= 73) 
OR (start_page = (SELECT max(start_page) FROM book WHERE start_page <= 92) AND end_page >= 92) 
OR (start_page = (SELECT max(start_page) FROM book WHERE start_page <= 300) AND end_page >= 300) 
+0

क्या यह विचार है कि आप एक प्रश्न में, कई पृष्ठों को सबमिट करने और परिणामस्वरूप प्राप्त करने के लिए, पृष्ठ संख्या वाले एक तालिका को उनके अध्याय के साथ जोड़ा गया है? –

+0

मुझे परिणाम में केवल अध्याय संख्याओं की एक तालिका की आवश्यकता है। मुझे पेज नंबरों के साथ जोड़ा जाने की आवश्यकता नहीं है। – Chip

+0

तो किसी भी तरह से आप 73, 92, 300 जैसे पृष्ठ संख्याओं का एक सेट सबमिट करना चाहते हैं और 3 और 5 वापस प्राप्त करना चाहते हैं, सही? –

उत्तर

0

दो समग्र सूचकांक में जोड़ें:

ALTER TABLE book 
    ADD INDEX `page_range_from_start` (start_page, end_page) 
    ADD INDEX `page_range_from_end` (end_page, start_page) 

और आगे बढ़ना आपकी मूल क्वेरी के साथ:

SELECT `chapter` 
FROM `book` 
WHERE 
    `start_page` <= 215 
    AND `end_page` >= 215 

MySQL सूचकांक स्तंभ है कि यह सबसे कम शेष पंक्तियों दे देंगे साथ प्रमुख का चयन करेंगे स्कैन करने के लिए, और उसके बाद एक वांछित पंक्ति (स्कैन के बिना) को कम करने के लिए इंडेक्स का दूसरा भाग होगा।

+0

मैंने मूल रूप से अपनी पहली क्वेरी के साथ यह कोशिश की। MySQL उन इंडेक्स का बहुत अच्छा लाभ नहीं लेता है और मेरी क्वेरी के आकार के कारण मेरे प्रश्नों में औसत कुछ सेकंड होते हैं। – Chip

+0

तुलना में - मेरी दूसरी क्वेरी औसत .0005 सेकंड एक ही टेबल पर। निश्चित रूप से तथ्य यह है कि मैं एक समय में केवल एक पृष्ठ से पूछताछ कर सकता हूं। – Chip

+0

दिलचस्प। क्या इंडेक्स को मजबूर करना कोई प्रभाव पड़ता है? –

0

बोहेमियन के INTERSECT समाधान के वाक्यात्मक मान्य समकक्ष (किसी तरह और बड़े में शामिल होने के बफर की एक अद्वितीय सूचकांक की आवश्यकता है):

SELECT 
    chapter 
FROM 
    book AS book_l 
    JOIN book AS book_r 
    USING (id) 
WHERE 
    book_l.start_page <= 215 
    AND book_r.end_page >= 215; 

या एक temptable दृष्टिकोण (start_page और end_page में से प्रत्येक पर एक भी सूचकांक की आवश्यकता है):

SELECT chapter FROM (
    SELECT * FROM book WHERE start_page <= 215 
    UNION 
    SELECT * FROM book WHERE end_page >= 215 
) AS derived WHERE start_page <= 215 AND end_page >= 215 
+0

मैंने इंडेक्स के साथ दोनों प्रश्नों की कोशिश की। पहली क्वेरी एक सेकंड के आसपास औसत लगती है जबकि दूसरा एक औसत लगभग 10 सेकंड होता है। – Chip

1

क्या यह उतना आसान नहीं है?

select max(chapter) 
from book 
where start_page <= 215; 

यदि अंतिम पृष्ठ पिछले प्रारंभ पृष्ठों का पालन करते हैं, तो यह काम करेगा।

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

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