নীচের সমস্তগুলি ইনোডিবিতে প্রযোজ্য।
আমি অনুভব করি 3 ভিন্ন পদ্ধতির গতি জেনে রাখা গুরুত্বপূর্ণ।
এখানে 3 টি পদ্ধতি রয়েছে:
- ইনসার্ট: অনুলিপি কী আপডেটের সাথে সন্নিবেশ করুন
- লেনদেন: যেখানে আপনি লেনদেনের মধ্যে প্রতিটি রেকর্ডের জন্য আপডেট করেন
- মামলা: আপনি কোনও ক্ষেত্রে / যখন কোনও আপডেটের মধ্যে প্রতিটি পৃথক রেকর্ডের জন্য
আমি কেবল এটি পরীক্ষা করেছি এবং INSERT পদ্ধতিটি আমার জন্য ট্রান্সঅ্যাকশন পদ্ধতির চেয়ে 6.7x দ্রুত ছিল । আমি 3,000 এবং 30,000 সারির উভয়ই সেটতে চেষ্টা করেছি।
ট্রান্সঅ্যাকশন পদ্ধতিতে এখনও প্রতিটি স্বতন্ত্র ক্যোয়ারী চালাতে হয়, যা সময় নেয় যদিও এটি কার্যকর করার সময় স্মৃতিতে বা কোনও কিছুতে ফলাফলগুলি ব্যাচ করে। প্রতিলিপি এবং ক্যোয়ারী লগ উভয় ক্ষেত্রে ট্রান্সএ্যাকশন পদ্ধতিটি বেশ ব্যয়বহুল।
এমনকি খারাপ, কেস পদ্ধতি ছিল 41.1x ঢোকান পদ্ধতি তুলনায় ধীর W / 30,000 রেকর্ড (6.1x লেনদেন তুলনায় ধীর)। এবং মাইআইএসএএম-তে 75x ধীর। INSERT এবং CASE পদ্ধতিগুলি এমনকি ~ 1000 রেকর্ডে ভেঙে গেছে। এমনকি 100 রেকর্ডে, CASE পদ্ধতিটি খুব কম দ্রুত AR
সুতরাং সাধারণভাবে, আমি মনে করি INSERT পদ্ধতিটি ব্যবহার করা সবচেয়ে ভাল এবং সহজ উভয়ই। প্রশ্নগুলি পড়ার জন্য আরও ছোট এবং সহজ এবং কেবলমাত্র 1 টি ক্রিয়াকলাপ গ্রহণ করে। এটি InnoDB এবং মাইআইএসএএম উভয় ক্ষেত্রেই প্রযোজ্য।
বোনাস স্টাফ:
ঢোকান অ ডিফল্ট-ক্ষেত্র সমস্যার জন্য সমাধান সাময়িকভাবে প্রাসঙ্গিক এসকিউএল মোড বন্ধ করতে হল: SET SESSION sql_mode=REPLACE(REPLACE(@@SESSION.sql_mode,"STRICT_TRANS_TABLES",""),"STRICT_ALL_TABLES","")
। আপনি sql_mode
যদি এটিকে ফিরিয়ে নেওয়ার পরিকল্পনা করেন তবে প্রথমটি সংরক্ষণ করার বিষয়টি নিশ্চিত করুন ।
অন্যান্য মন্তব্য হিসাবে আমি দেখেছি যে বলে যে অটো_সংগ্রহটি INSERT পদ্ধতি ব্যবহার করে উপরে উঠে যায়, এটি InnoDB তে দেখা যায়, তবে মাইআইএসএএম-তে নয় not
টেস্টগুলি চালানোর কোডটি নিম্নরূপ। এটি পিএইচপি ইন্টারপ্রেটারের ওভারহেড অপসারণ করতে। এসকিউএল ফাইলগুলি আউটপুট করে
<?
//Variables
$NumRows=30000;
//These 2 functions need to be filled in
function InitSQL()
{
}
function RunSQLQuery($Q)
{
}
//Run the 3 tests
InitSQL();
for($i=0;$i<3;$i++)
RunTest($i, $NumRows);
function RunTest($TestNum, $NumRows)
{
$TheQueries=Array();
$DoQuery=function($Query) use (&$TheQueries)
{
RunSQLQuery($Query);
$TheQueries[]=$Query;
};
$TableName='Test';
$DoQuery('DROP TABLE IF EXISTS '.$TableName);
$DoQuery('CREATE TABLE '.$TableName.' (i1 int NOT NULL AUTO_INCREMENT, i2 int NOT NULL, primary key (i1)) ENGINE=InnoDB');
$DoQuery('INSERT INTO '.$TableName.' (i2) VALUES ('.implode('), (', range(2, $NumRows+1)).')');
if($TestNum==0)
{
$TestName='Transaction';
$Start=microtime(true);
$DoQuery('START TRANSACTION');
for($i=1;$i<=$NumRows;$i++)
$DoQuery('UPDATE '.$TableName.' SET i2='.(($i+5)*1000).' WHERE i1='.$i);
$DoQuery('COMMIT');
}
if($TestNum==1)
{
$TestName='Insert';
$Query=Array();
for($i=1;$i<=$NumRows;$i++)
$Query[]=sprintf("(%d,%d)", $i, (($i+5)*1000));
$Start=microtime(true);
$DoQuery('INSERT INTO '.$TableName.' VALUES '.implode(', ', $Query).' ON DUPLICATE KEY UPDATE i2=VALUES(i2)');
}
if($TestNum==2)
{
$TestName='Case';
$Query=Array();
for($i=1;$i<=$NumRows;$i++)
$Query[]=sprintf('WHEN %d THEN %d', $i, (($i+5)*1000));
$Start=microtime(true);
$DoQuery("UPDATE $TableName SET i2=CASE i1\n".implode("\n", $Query)."\nEND\nWHERE i1 IN (".implode(',', range(1, $NumRows)).')');
}
print "$TestName: ".(microtime(true)-$Start)."<br>\n";
file_put_contents("./$TestName.sql", implode(";\n", $TheQueries).';');
}