कृपया, ORDER BY RAND()
का उपयोग करना बंद करें . अभी रोको। इस ऑपरेशन में n*log2(n)
. की जटिलता है , जिसका अर्थ है कि क्वेरी पर बिताया गया समय बढ़ जाएगा "
entries | time units
-------------------------
10 | 1 /* if this takes 0.001s */
1'000 | 300
1'000'000 | 600'000 /* then this will need 10 minutes */
यदि आप यादृच्छिक परिणाम उत्पन्न करना चाहते हैं, तो एक संग्रहीत कार्यविधि बनाएं, जो उन्हें उत्पन्न करती है। कुछ इस तरह (इस लेख से लिया गया कोड , जिसे आपको पढ़ना चाहिए):
DELIMITER $$
DROP PROCEDURE IF EXISTS get_rands$$
CREATE PROCEDURE get_rands(IN cnt INT)
BEGIN
DROP TEMPORARY TABLE IF EXISTS rands;
CREATE TEMPORARY TABLE rands ( tagname VARCHAR(63) );
loop_me: LOOP
IF cnt < 1 THEN
LEAVE loop_me;
END IF;
SET cnt = cnt - 1;
INSERT INTO rands
SELECT tags.tagname
FROM tags
JOIN (SELECT (RAND()*(SELECT MAX(tags.id) FROM tags)) AS id) AS choices
WHERE tags.id >= choices.id
LIMIT 1;
END LOOP loop_me;
END$$
DELIMITER ;
और इसका इस्तेमाल करने के लिए आप लिखेंगे:
CALL get_rands(10);
SELECT * FROM rands;
जहां तक PHP की तरफ से इसे क्रियान्वित करने की बात है, तो आपको प्राचीन mysql_*
. का उपयोग बंद कर देना चाहिए एपीआई। यह 10 साल से अधिक पुराना है और अब इसका रखरखाव नहीं किया जाता है। समुदाय ने प्रक्रिया शुरू कर दी है
उनकी अवहेलना करने के लिए। mysql_*
. के साथ कोई और नया कोड नहीं लिखा जाना चाहिए 2012 में। इसके बजाय आपको PDO
का उपयोग करना चाहिए या MySQLi
. इसे कैसे लिखना है (पीडीओ के साथ):
// creates DB connection
$connection = new PDO('mysql:host=localhost;dbname=mydb;charset=UTF-8',
'username', 'password');
$connection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
// executes the procedure and creates select statement
$connection->exec('CALL get_rands(10)');
$statement = $connection->query('SELECT * FROM rands');
// performs query and collects all the info
if ($statement->execute())
{
$tags = $statement->fetchAll(PDO::FETCH::ASSOC);
}
अपडेट करें
यदि आवश्यकता न केवल 10 यादृच्छिक परिणाम प्राप्त करने की है, बल्कि वास्तव में 10 अद्वितीय यादृच्छिक परिणाम . है , तो इसे PROCEDURE
. में दो बदलावों की आवश्यकता होगी :
-
अस्थायी तालिका को प्रविष्टियों की विशिष्टता को लागू करना चाहिए:
CREATE TEMPORARY TABLE rands ( tagname VARCHAR(63) UNIQUE);
यह केवल आईडी एकत्र करने के लिए भी समझ में आता है, न कि मूल्यों को। विशेष रूप से यदि आप जो खोज रहे हैं वह 10 अद्वितीय लेख हैं, न कि केवल टैग।
-
डुप्लिकेट मान डालने पर पाया जाता है,
cnt
काउंटर कम नहीं होना चाहिए। यह एकHANDLER
adding जोड़कर सुनिश्चित किया जा सकता है (LOOP
. की परिभाषा से पहले ), जो उठाए गए चेतावनी को "पकड़" लेगा, और काउंटर को समायोजित करेगा:DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET cnt = cnt + 1;