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

वाक्पटु में दो अभिलेखों के बीच मूल्य अंतर की गणना करना

फिर मेरे पास आपके लिए एक सरप्राइज है - यहां एक छोटा प्रदर्शन परीक्षण है:

class Seq extends Eloquent {
    protected $table = 'helper.seq';
    protected $primaryKey = 'i';
}

Route::get('/loop', function () {
    $limit = 10000;

    $st = microtime(true);
    $data = Seq::orderBy('i')->take($limit)->get();
    var_dump(microtime(true) - $st);

    $st = microtime(true);
    foreach ($data as $row) {
        $row->i;
    }
    var_dump(microtime(true) - $st);

    $pdo = DB::getPdo();
    $st = microtime(true);
    $data2 = $pdo
        ->query("select * from helper.seq order by i limit $limit")
        ->fetchAll(PDO::FETCH_OBJ);
    var_dump(microtime(true) - $st);

    $st = microtime(true);
    foreach ($data2 as $k => $row) {
        if ($k == 0) {
            $row->diff = 0;
        } else {
            $row->diff = $row->i - $data2[$k-1]->i;
        }
    }
    var_dump(microtime(true) - $st);
});

helper.seq केवल एक इंट कॉलम और 1M पंक्तियों वाली एक तालिका है।

और परिणाम यह है:

0.779045s <- Fetch from DB with Eloquent

1.022058s <- Read Eloquent data (Only one column and do nothing with it)

0.020002s <- Fetch from DB with PDO

0.009999s <- Calculate all diffs in a loop

तो "वाक्पटु से छोटा प्रदर्शन प्रभाव" है:

  • सादे पीडीओ और stdClass का उपयोग करने की तुलना में लगभग 20 गुना धीमा डेटाबेस से डेटा लाते समय।
  • stdClass . से कम से कम 100 गुना धीमा लूप में गुण/गुण पढ़ते समय।

इसलिए यदि आप प्रदर्शन में सुधार करना चाहते हैं, तो बड़ी मात्रा में डेटा के साथ काम करते समय सादे पीडीओ पर स्विच करें या कम से कम डिफ़ॉल्ट बिल्डर का उपयोग करें।

अब आप अभी भी MySQL में काम करने की कोशिश कर सकते हैं, लेकिन एलोक्वेंट का उपयोग करने की आवश्यकता समझ में नहीं आएगी।

हालाँकि आप एक मिश्रित संस्करण आज़मा सकते हैं - क्वेरी बनाने के लिए वाक्पटु का उपयोग करें, लेकिन इसे Database\Query\Builder में बदलें getQuery() . के साथ .

$fooBars = FooBar::where('type', 'FOO')->orderBy('id')
    ->getQuery()
    ->select(['*', DB::raw('coalesce(`value` - @last, 0)'), DB::raw('@last := `value`')])
    ->get();

लेकिन मैं हमेशा इस तरह से एप्लिकेशन कोड में सत्र चर का उपयोग करने से बचूंगा, क्योंकि मैंने ऐसे कई समाधान देखे हैं जो संस्करण अपग्रेड के बाद गलत/अप्रत्याशित परिणाम लौटाते हैं।

अभी भी आश्वस्त नहीं हैं? यहां कुछ अन्य परीक्षण दिए गए हैं:

एक वाक्पटु क्वेरी में सत्र चर का उपयोग करना Database\Query\Builder . में कनवर्ट किया गया :

$st = microtime(true);
$data = Seq::getQuery()
    ->select(['*', DB::raw('coalesce(i - @last, 0)'), DB::raw('@last := i')])
    ->orderBy('i')->take($limit)->get();
var_dump(microtime(true) - $st);

// runtime: 0.045002s

परिवर्तित वाक्पटु क्वेरी का उपयोग कर PHP समाधान:

$st = microtime(true);
$data2 = Seq::getQuery()->orderBy('i')->take($limit)->get();
foreach ($data2 as $k => $row) {
    if ($k == 0) {
        $row->diff = 0;
    } else {
        $row->diff = $row->i - $data2[$k-1]->i;
    }
}
var_dump(microtime(true) - $st);

// runtime: 0.039002

सादा पीडीओ और stdClass . के साथ PHP समाधान

$st = microtime(true);
$data3 = $pdo
    ->query("select * from helper.seq s1 order by i limit $limit")
    ->fetchAll(PDO::FETCH_OBJ);
foreach ($data3 as $k => $row) {
    if ($k == 0) {
        $row->diff = 0;
    } else {
        $row->diff = $row->i - $data3[$k-1]->i;
    }
}
var_dump(microtime(true) - $st);

// runtime: 0.035001s

सादा पीडीओ और सहयोगी सरणियों के साथ PHP समाधान:

$st = microtime(true);
$data4 = $pdo
    ->query("select * from helper.seq s1 order by i limit $limit")
    ->fetchAll(PDO::FETCH_ASSOC);
foreach ($data4 as $k => $row) {
    if ($k == 0) {
        $row['diff'] = 0;
    } else {
        $row['diff'] = $row['i'] - $data4[$k-1]['i'];
    }
}
var_dump(microtime(true) - $st);

// runtime: 0.027001s

आपका पसंदीदा समाधान सबसे धीमा और सबसे कम विश्वसनीय है। तो आपके प्रश्न का उत्तर आपकी समस्या का एक बुरा समाधान है।




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. मुझे $wpdb->तैयार करने का उपयोग कब करना चाहिए, यदि बिल्कुल भी?

  2. MySQL pid समाप्त हो गया (mysql प्रारंभ नहीं कर सकता)

  3. शीर्ष दस MySQL GUI उपकरण

  4. डेटाबेस से कनेक्ट नहीं हो सकता (000webhost)

  5. मैं MySQL का वर्तमान समय क्षेत्र कैसे प्राप्त करूं?