दिलचस्प पोस्ट
कॉर्डोबा एंड्रॉइड को एक्सेक्ट कोड ENOENT के साथ नहीं जोड़ा जा सकता है जरूरत पड़ने पर निर्भरता बनाने के लिए XCode 4 कार्यस्थान को कॉन्फ़िगर करने का सही तरीका क्या है? मेरे पास PHP में दो तिथियां हैं, मैं उन दिनों के माध्यम से जाने के लिए कैसे एक foreach पाश चला सकता हूँ? Java String.equals बनाम == नीलेबर्ड वादों के साथ असिंक्रोनस अपवाद हैंडलिंग विम में एक कमांड को अलग करना जावास्क्रिप्ट Regexp गति से गतिशील पीढ़ी? प्रेषक को छोड़कर सभी ग्राहकों को प्रतिक्रिया भेजें मैं अपनी साइट पर अद्वितीय आगंतुकों को कैसे गणना करूं? मोंगो डीबी / मोंगोज: अनूठे यदि नल नहीं है सी – फ्लोटिंग प्वाइंट नंबर का क्रमबद्धकरण (फ्लोट्स, डबल्स) ओपनसीवी बिंदु (एक्स, वाई) (स्तंभ, पंक्ति) या (पंक्ति, स्तंभ) का प्रतिनिधित्व करते हैं INSTALL_FAILED_UPDATE_INCOMPATIBLE जब मैं डिवाइस पर संकलित। एपीक स्थापित करने का प्रयास करता / करती हूं वेबकिट में अनपेक्षित टोकन अवैध स्ट्रिंग, स्ट्रिंगबफर, और स्ट्रिंगबइल्डर

पोस्टग्रेज़ में त्वरित यादृच्छिक पंक्ति चयन

मेरे पास पोस्टग्रेज़ में एक टेबल है जिसमें लाखों पंक्तियाँ हैं। मैंने इंटरनेट पर चेक किया है और मुझे निम्नलिखित मिले

SELECT myid FROM mytable ORDER BY RANDOM() LIMIT 1; 

यह काम करता है, लेकिन यह वास्तव में धीमा है … क्या उस क्वेरी को बनाने का एक और तरीका है, या सभी तालिका पढ़ने के बिना एक यादृच्छिक पंक्ति का चयन करने का एक सीधा तरीका है? जिस तरह से 'मैरीड' एक पूर्णांक है, लेकिन यह एक खाली क्षेत्र हो सकता है

धन्यवाद

Solutions Collecting From Web of "पोस्टग्रेज़ में त्वरित यादृच्छिक पंक्ति चयन"

आप OFFSET साथ प्रयोग करना चाहें, जैसे में

SELECT myid FROM mytable OFFSET floor(random()*N) LIMIT 1;

N mytable में पंक्तियों की संख्या है N के मान को समझने के लिए पहले आपको एक SELECT COUNT(*) करना पड़ सकता है।

अपडेट (एंटनी हैचकिंस द्वारा)

आपको यहां floor का उपयोग करना होगा:

 SELECT myid FROM mytable OFFSET floor(random()*N) LIMIT 1; 

2 पंक्तियों की एक तालिका पर विचार करें; random()*N 0 <= x < 2 उत्पन्न करता है और उदाहरण के लिए SELECT myid FROM mytable OFFSET 1.7 LIMIT 1; निकटतम अंतर के लिए अंतर्निहित गोल के कारण 0 पंक्तियां लौटाता है

मैंने इसे एक सबक्यूरी के साथ करने की कोशिश की और यह ठीक काम किया। ऑफसेट, कम से कम Postgresql v8.4.4 में ठीक काम करता है।

 select * from mytable offset random() * (select count(*) from mytable) limit 1 ; 

पोस्टग्रेएसक्यूएल 9.5 ने बहुत तेजी से नमूना चयन के लिए एक नया दृष्टिकोण पेश किया: टैब्लेसम

वाक्यविन्यास है

 SELECT * FROM my_table TABLESAMPLE BERNOULLI(percentage); SELECT * FROM my_table TABLESAMPLE SYSTEM(percentage); 

यह इष्टतम समाधान नहीं है यदि आप केवल एक ही पंक्ति चुनना चाहते हैं, क्योंकि आपको सटीक प्रतिशत की गणना करने के लिए तालिका के COUNT पता करने की आवश्यकता है।

धीमे COUNT से बचने के लिए और तालिकाओं के लिए 1 पंक्ति से अरबों पंक्तियों के लिए तेज़ टेबल्स का उपयोग करें, आप ऐसा कर सकते हैं:

  SELECT * FROM my_table TABLESAMPLE SYSTEM(0.000001) LIMIT 1; if you got no result: SELECT * FROM my_table TABLESAMPLE SYSTEM(0.00001) LIMIT 1; if you got no result: SELECT * FROM my_table TABLESAMPLE SYSTEM(0.0001) LIMIT 1; if you got no result: SELECT * FROM my_table TABLESAMPLE SYSTEM(0.001) LIMIT 1; ... 

यह बहुत खूबसूरत नहीं दिख सकता है, लेकिन संभवतः अन्य उत्तरों में से किसी की तुलना में तेज़ है।

यह तय करने के लिए कि आप ब्रेन्युली ओडर सिस्टम का उपयोग करना चाहते हैं, http://blog.2ndquadrant.com/tablesample-in-postgresql-9-5-2/ पर अंतर के बारे में पढ़ें

आपको floor का उपयोग करने की आवश्यकता है:

 SELECT myid FROM mytable OFFSET floor(random()*N) LIMIT 1; 

कुछ अलग विकल्पों के लिए इस लिंक को देखें http://www.depesz.com/index.php/2007/09/16/my-thoughts-on-getting-random-row/

अद्यतन: (एएचचकिंस)

(बहुत) लंबे लेख का सारांश इस प्रकार है:

लेखक चार दृष्टिकोणों को सूचीबद्ध करता है:

1) ORDER BY random() LIMIT 1; धीमा

2) ORDER BY id where id>=random()*N LIMIT 1 – यदि कोई अंतराल नहीं है तो

3) यादृच्छिक स्तंभ – अब हर बार अपडेट किए जाने की आवश्यकता है

4) कस्टम यादृच्छिक कुल – चालाक विधि, धीमा हो सकता है: यादृच्छिक () एन बार उत्पन्न होने की आवश्यकता है

और इसका उपयोग करके विधि # 2 को सुधारने का सुझाव दिया है

5) ORDER BY id where id=random()*N LIMIT 1 परिणामस्वरूप रिक्त है, यदि आवश्यक है।

मैं TABLESAMPLE बिना बहुत तेज़ समाधान के साथ आया हूं OFFSET random()*N LIMIT 1 से अधिक तेज़ OFFSET random()*N LIMIT 1 इसमें टेबल की गिनती भी नहीं होती है

यह विचार यादृच्छिक लेकिन उम्मीद के मुताबिक आंकड़ों के साथ अभिव्यक्ति अनुक्रमणिका बनाने के लिए है, उदाहरण के लिए md5(primary key)

यहां 1M पंक्तियों का नमूना डेटा वाला परीक्षण है:

 create table randtest (id serial primary key, data int not null); insert into randtest (data) select (random()*1000000)::int from generate_series(1,1000000); create index randtest_md5_id_idx on randtest (md5(id::text)); explain analyze select * from randtest where md5(id::text)>md5(random()::text) order by md5(id::text) limit 1; 

परिणाम:

  Limit (cost=0.42..0.68 rows=1 width=8) (actual time=6.219..6.220 rows=1 loops=1) -> Index Scan using randtest_md5_id_idx on randtest (cost=0.42..84040.42 rows=333333 width=8) (actual time=6.217..6.217 rows=1 loops=1) Filter: (md5((id)::text) > md5((random())::text)) Rows Removed by Filter: 1831 Total runtime: 6.245 ms 

यह क्वेरी कभी-कभी (लगभग 1 / number_of_rows संभावना के साथ) 0 पंक्तियों को वापस आती है, इसलिए उसे चेक और फिर से चलाने की आवश्यकता है। इसके अलावा संभावनाएं बिल्कुल समान नहीं हैं – कुछ पंक्तियां दूसरों की तुलना में अधिक संभावित हैं

तुलना के लिए:

 explain analyze SELECT id FROM randtest OFFSET random()*1000000 LIMIT 1; 

परिणाम व्यापक रूप से भिन्न होते हैं, लेकिन बहुत बुरा हो सकता है:

  Limit (cost=1442.50..1442.51 rows=1 width=4) (actual time=179.183..179.184 rows=1 loops=1) -> Seq Scan on randtest (cost=0.00..14425.00 rows=1000000 width=4) (actual time=0.016..134.835 rows=915702 loops=1) Total runtime: 179.211 ms (3 rows)