2013-05-22 9 views
5

मैं इस तालिका है यादृच्छिक पंक्तियों वितरित,MySQL समान रूप से साथ कहां खंड

person_id int(10) pk 
points  int(6) index 
other columns not very important 

मैं इस यादृच्छिक समारोह जो 10M पंक्तियों के साथ एक मेज पर बहुत तेजी से होता है:

SELECT person_id 
    FROM persons AS r1 JOIN 
     (SELECT (RAND() * 
        (SELECT MAX(person_id) 
         FROM persons)) AS id) 
     AS r2 
WHERE r1.person_id >= r2.id 
ORDER BY r1.person_id ASC 
LIMIT 1 

यह सब बहुत अच्छा है लेकिन अब मैं अंक> 0. उदाहरण तालिका के साथ ही लोगों को दिखाने के लिए चाहते हैं:

PERSON_ID  POINTS 
1    4 
2    6 
3    0 
4    3 

जब मैं संलग्न AND points > 0 जहां खंड में, person_id 3 का चयन नहीं किया जा सकता है, इसलिए एक अंतर बनाया गया है और जब यादृच्छिक चयन person_id 3, person_id 4 का चयन किया जाएगा। यह व्यक्ति को 4 चुनने का एक बड़ा मौका देता है। किसी को भी सुझाव मिल गया है कि मैं इस खंड के साथ काम करने के लिए क्वेरी को कैसे समायोजित कर सकता हूं और सभी पंक्तियों को चुनने का मौका%% दे सकता हूं।

जानकारी तालिका: तालिका समान है, person_id में कोई अंतर नहीं है। लगभग 9 0% के पास 0 अंक होंगे। मैं कहाँ अंक = 0 और अंक> 0.

पहले कोई कहेगा, rand() का उपयोग के लिए क्वेरी बनाना चाहते: इस के साथ टेबल के लिए समाधान में कुछ 100k पंक्तियों से अधिक नहीं है।

बोनस प्रश्न: क्या 1 क्वेरी में एक्स यादृच्छिक पंक्तियों का चयन करना संभव होगा, इसलिए मुझे इस क्वेरी को कुछ बार कॉल करने की आवश्यकता नहीं है जब मुझे और यादृच्छिक पंक्तियां चाहिए?

महत्वपूर्ण नोट: प्रदर्शन की कुंजी है, 10M + पंक्तियों के साथ क्वेरी बहुत लंबे समय तक वर्तमान क्वेरी, जो 0.0005 सेकंड लेता है की तुलना में नहीं लग सकता है, मैं 0.05 सेकंड के तहत रहना पसंद करते हैं।

अंतिम टिप्पणी: यदि आपको लगता क्वेरी ऊपर दी गई आवश्यकताओं के साथ तेजी से इस कभी नहीं होगा, लेकिन एक और समाधान संभव है (100 पंक्तियों लाए जाने और यादृच्छिक एक्स जो 0 से अधिक अंक हैं दिखा) की तरह, कृपया बताओ :)

सच तुम्हारी मदद की सराहना करते हैं और सभी मदद का स्वागत करते हैं :) है

+0

मूल कार्य क्या है? पीके एक कृत्रिम (अनुक्रम आधारित) पूर्णांक है? यह कितना स्पैस है? – zerkms

+0

10 एम पंक्तियों वाली तालिका, कम से कम 1 बिंदु के साथ 4 यादृच्छिक पंक्तियों की आवश्यकता है, व्यक्ति_आईडी वर्दी (1,2,3,4 आदि, कोई अंतराल नहीं है), लेकिन कुछ में 0 अंक हो सकते हैं, इसलिए वे अंतराल बनाते हैं .. –

+0

तो वहां कोई प्राथमिक कुंजी नहीं है? – zerkms

उत्तर

1

आप में लाइन खाई से मुक्त आईडी रिकॉर्ड है कि तुम सच के साथ काम करना चाहते हैं के लिए के उत्पन्न कर सकता है, और की कुल संख्या का उपयोग कर तो यादृच्छिक चयनकर्ता उत्पन्न रिकॉर्ड उपलब्ध हैं। इस के साथ

कोशिश (ROW_NUMBER जनरेटर के लिए चुना जवाब here को रंगमंच की सामग्री): this sqlfiddle में इसके साथ

गड़बड़
SELECT r1.* 
    FROM 
     (SELECT person_id, 
       @curRow := @curRow + 1 AS row_number 
     FROM persons as p, 
      (SELECT @curRow := 0) r0 
     WHERE points>0) r1 
    , (SELECT COUNT(1) * RAND() id 
     FROM persons 
     WHERE points>0) r2 
    WHERE r1.person_id>=r2.id 
    ORDER BY r1.person_id ASC 
    LIMIT 1; 

आप कर सकते हैं।

+0

बहुत धन्यवाद, मैं आज रात का परीक्षण करूंगा और आपको प्रदर्शन को जानने और उत्तर स्वीकार करने के लिए :) –

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