फिर मेरे पास आपके लिए एक सरप्राइज है - यहां एक छोटा प्रदर्शन परीक्षण है:
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
आपका पसंदीदा समाधान सबसे धीमा और सबसे कम विश्वसनीय है। तो आपके प्रश्न का उत्तर आपकी समस्या का एक बुरा समाधान है।