Mysql
 sql >> डेटाबेस >  >> RDS >> Mysql

अलग-अलग पंक्तियों पर अलग-अलग शर्तों को पूरा करने वाले मानों का चयन करें?

ठीक है, मुझे इस पर वोट नहीं मिला इसलिए मैंने इसका परीक्षण करने का फैसला किया:

CREATE TABLE userrole (
  userid INT,
  roleid INT,
  PRIMARY KEY (userid, roleid)
);

CREATE INDEX ON userrole (roleid);

इसे चलाएं:

<?php
ini_set('max_execution_time', 120); // takes over a minute to insert 500k+ records 

$start = microtime(true);

echo "<pre>\n";
mysql_connect('localhost', 'scratch', 'scratch');
if (mysql_error()) {
    echo "Connect error: " . mysql_error() . "\n";
}
mysql_select_db('scratch');
if (mysql_error()) {
    echo "Selct DB error: " . mysql_error() . "\n";
}

$users = 200000;
$count = 0;
for ($i=1; $i<=$users; $i++) {
    $roles = rand(1, 4);
    $available = range(1, 5);
    for ($j=0; $j<$roles; $j++) {
        $extract = array_splice($available, rand(0, sizeof($available)-1), 1);
        $id = $extract[0];
        query("INSERT INTO userrole (userid, roleid) VALUES ($i, $id)");
        $count++;
    }
}

$stop = microtime(true);
$duration = $stop - $start;
$insert = $duration / $count;

echo "$count users added.\n";
echo "Program ran for $duration seconds.\n";
echo "Insert time $insert seconds.\n";
echo "</pre>\n";

function query($str) {
    mysql_query($str);
    if (mysql_error()) {
        echo "$str: " . mysql_error() . "\n";
    }
}
?>
\n";फंक्शन क्वेरी($str) {mysql_query($str); अगर (mysql_error ()) {गूंज "$ str:"। mysql_error ()। "\एन"; }}?>

आउटपुट:

499872 users added.
Program ran for 56.5513510704 seconds.
Insert time 0.000113131663847 seconds.

यह 500,000 यादृच्छिक उपयोगकर्ता-भूमिका संयोजन जोड़ता है और लगभग 25,000 हैं जो चुने हुए मानदंड से मेल खाते हैं।

पहली क्वेरी:

SELECT userid
FROM userrole
WHERE roleid IN (1, 2, 3)
GROUP by userid
HAVING COUNT(1) = 3

क्वेरी समय:0.312s

SELECT t1.userid
FROM userrole t1
JOIN userrole t2 ON t1.userid = t2.userid AND t2.roleid = 2
JOIN userrole t3 ON t2.userid = t3.userid AND t3.roleid = 3
AND t1.roleid = 1

क्वेरी समय:0.016s

ये सही है। मेरे द्वारा प्रस्तावित शामिल संस्करण समग्र संस्करण से बीस गुना तेज है।

क्षमा करें, लेकिन मैं इसे वास्तविक दुनिया में रहने और काम करने के लिए करता हूं और वास्तविक दुनिया में हम SQL का परीक्षण करते हैं और परिणाम अपने लिए बोलते हैं।

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

मिलान संस्करण का प्रदर्शन मैचों की कम घटनाओं के साथ और भी बेहतर हो जाता है।

यदि केवल 500 उपयोगकर्ता थे (उपरोक्त 500k नमूने में से) जिनकी तीन बताई गई भूमिकाएँ थीं, तो शामिल होने का संस्करण काफी तेज़ हो जाएगा। कुल संस्करण नहीं होगा (और कोई भी प्रदर्शन सुधार 25k के बजाय 500 उपयोगकर्ताओं को परिवहन का परिणाम है, जो कि शामिल संस्करण भी स्पष्ट रूप से प्राप्त होता है)।

मैं यह देखने के लिए भी उत्सुक था कि एक वास्तविक डेटाबेस (यानी ओरेकल) इससे कैसे निपटेगा। इसलिए मैंने मूल रूप से Oracle XE पर वही अभ्यास दोहराया (पिछले उदाहरण से MySQL के समान Windows XP डेस्कटॉप मशीन पर चल रहा है) और परिणाम लगभग समान हैं।

ऐसा लगता है कि जुड़ने पर गुस्सा आता है, लेकिन जैसा कि मैंने दिखाया है, कुल क्वेरी परिमाण का क्रम धीमा हो सकता है।

अपडेट करें: कुछ व्यापक परीक्षण के बाद , चित्र अधिक जटिल है और उत्तर आपके डेटा, आपके डेटाबेस और अन्य कारकों पर निर्भर करेगा। कहानी का नैतिक परीक्षण, परीक्षण, परीक्षण है।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL कई स्तंभों का चयन करें

  2. MySQL शेल (प्लस MySQL राउटर) के साथ MySQL InnoDB क्लस्टर की स्थापना

  3. कौन सी SQL क्वेरी बेहतर है, इसके विरुद्ध मिलान करें या LIKE करें?

  4. MySQL इंडेक्स कैसे काम करते हैं?

  5. MySQL डेटाबेस इंजन के साथ कार्य करना