মাইএসকিউএলে একাধিক আপডেট


388

আমি জানি যে আপনি একবারে একাধিক সারি সন্নিবেশ করতে পারেন, মাইএসকিউএলে একবারে একাধিক সারি (যেমন, একটি ক্যোয়ারিতে) আপডেট করার কোনও উপায় আছে?

সম্পাদনা করুন: উদাহরণস্বরূপ আমার কাছে নিম্নলিখিতগুলি রয়েছে

Name   id  Col1  Col2
Row1   1    6     1
Row2   2    2     3
Row3   3    9     5
Row4   4    16    8

আমি নীচের সমস্ত আপডেটগুলি একটি ক্যোয়ারিতে একত্রিত করতে চাই

UPDATE table SET Col1 = 1 WHERE id = 1;
UPDATE table SET Col1 = 2 WHERE id = 2;
UPDATE table SET Col2 = 3 WHERE id = 3;
UPDATE table SET Col1 = 10 WHERE id = 4;
UPDATE table SET Col2 = 12 WHERE id = 4;

উত্তর:


651

হ্যাঁ, এটি সম্ভব - আপনি সংবিধান ব্যবহার করতে পারেন ... কী কী আপডেটের জন্য UP

আপনার উদাহরণ ব্যবহার করে:

INSERT INTO table (id,Col1,Col2) VALUES (1,1,1),(2,2,3),(3,9,3),(4,10,12)
ON DUPLICATE KEY UPDATE Col1=VALUES(Col1),Col2=VALUES(Col2);

22
যদি কোনও সদৃশ না থাকে তবে আমি চাই না যে সারিটি sertedোকানো হোক। আইডি কি করা উচিত? কারণ আমি অন্য সাইট থেকে তথ্য আনছি যা আইডির টেবিলগুলি বজায় রাখে। আমি সেই আইডির সম্মানের সাথে মান সন্নিবেশ করছি। সাইটে যদি নতুন রেকর্ড থাকে তবে আমি কেবলমাত্র আইডির সন্নিবেশ করব এবং অন্য সমস্ত তথ্য ব্যতীত গণনা করব। যদি এবং কেবল যদি আইডির জন্য কোনও এন্ট্রি থাকে তবে তা আপডেট করা উচিত অন্যথায় এটি এড়ানো উচিত নয়। আমি এখন কি করব?
জয়পাল চন্দ্রন

33
দ্রষ্টব্য: এই উত্তরটি আইডি প্রাথমিক কী
জেএম 4

11
@ জয়পাল চন্দ্রাণ আপনার অন-ইপলিটার অন ডুপ্লিকেট কী আপডেটের সাথে একসাথে ব্যবহার করা উচিত। dev.mysql.com/doc/refman/5.5/en/insert.html
হারালান দোব্রেভ

16
@ হারালানডোব্রেভ INSERT IGNORE ব্যবহার করে এখনও অনুলিপিবিহীন রেকর্ড সন্নিবেশ করানো হয়েছে। যা জয়পাল এড়াতে চেয়েছিলেন। ঢোকান উপেক্ষা করুন মাত্র সতর্কীকরণ :( মধ্যে কোনো ত্রুটি সক্রিয় stackoverflow.com/questions/548541/...
Takehiro Adachi

2
এই উত্তরটি ধরে নিয়েছে যে আইডিটি একটি অনন্য কী (অন্যরা যেমনটি বলেছিলেন প্রাথমিক হতে পারে) তবে আরও গুরুত্বপূর্ণ বিষয় এটি ধরে নেয় যে অন্য কোনও অনন্য কী নেই। যদি কোনও থাকে তবে এটি কাজগুলিতে একটি স্প্যানার ফেলে দিতে পারে।
স্টিভ হরভাথ

129

যেহেতু আপনার গতিশীল মান রয়েছে তাই কলামগুলি আপডেট করার জন্য আপনাকে একটি আইএফ বা সিএসই ব্যবহার করতে হবে। এটি কৃপণ হয়ে ওঠে, তবে এটি কাজ করা উচিত।

আপনার উদাহরণ ব্যবহার করে, আপনি এটি এর মতো করতে পারেন:

আপডেট টেবিল SET কল 1 = কেস আইডি 
                          যখন 1 তখন 1 
                          যখন 2 তম 2 
                          যখন 4 তখন 10 
                          ELSE কল 1 
                        শেষ, 
                 কল 2 = সিএসই আইডি 
                          যখন 3 তখন 3 
                          যখন 4 তখন 12 
                          ELSE কল 2 
                        শেষ
             যেখানে আইডি ইন (1, 2, 3, 4);

ডায়নামিক
আপডেটিংয়ের

1
@ ব্যবহারকারী 2536953, এটি গতিশীল আপডেট করার জন্যও দুর্দান্ত হতে পারে। উদাহরণস্বরূপ, আমি পিএইচপি-তে লুপে সেই সমাধানটি ব্যবহার করেছি:$commandTxt = 'UPDATE operations SET chunk_finished = CASE id '; foreach ($blockOperationChecked as $operationID => $operationChecked) $commandTxt .= " WHEN $operationID THEN $operationChecked "; $commandTxt .= 'ELSE id END WHERE id IN ('.implode(', ', array_keys(blockOperationChecked )).');';
বুলিয়ান_টাইপ

86

প্রশ্নটি পুরানো, তবুও আমি আরও একটি উত্তর দিয়ে বিষয়টি প্রসারিত করতে চাই।

আমার বক্তব্যটি হ'ল, এটি অর্জনের সবচেয়ে সহজ উপায় হ'ল কেবল কোনও লেনদেনের সাথে একাধিক প্রশ্ন মোড়ানো w গৃহীত উত্তরটি INSERT ... ON DUPLICATE KEY UPDATEএকটি দুর্দান্ত হ্যাক, তবে এর অপূর্ণতা এবং সীমাবদ্ধতা সম্পর্কে একটি সচেতন হওয়া উচিত:

  • যেমনটি বলা হচ্ছে, আপনি যদি সারিগুলির সাথে কোয়েরিটি চালু করতে যাঁর প্রাথমিক কীগুলি সারণীতে উপস্থিত নেই, কোয়েরিতে নতুন "অর্ধ-বেকড" রেকর্ড সন্নিবেশ করা হয়েছে। সম্ভবত এটি আপনি যা চান তা নয়
  • যদি আপনার ডিফল্ট মান ব্যতীত নাল নয় ক্ষেত্র সহ একটি টেবিল থাকে এবং কোয়েরিতে এই ক্ষেত্রটি স্পর্শ করতে না চান "Field 'fieldname' doesn't have a default value"তবে আপনি মাইএসকিউএল সতর্কতা পাবেন এমনকি আপনি যদি কোনও একক সারি প্রবেশ নাও করেন তবেও। যদি আপনি কঠোর হওয়ার সিদ্ধান্ত নেন এবং মাইএসকিএল সতর্কতাগুলি আপনার অ্যাপ্লিকেশনটিতে রানটাইম ব্যতিক্রমগুলিতে পরিণত করেন তবে এটি আপনাকে সমস্যার মধ্যে ফেলবে।

আমি প্রস্তাবিত তিনটি ভেরিয়েন্টের জন্য কয়েকটি কার্য সম্পাদন টেস্ট করেছি, যার মধ্যে INSERT ... ON DUPLICATE KEY UPDATEভেরিয়েন্ট, "কেস / যখন / তারপরে" ধারা এবং একটি লেনদেনের সাথে একটি নিষ্পাপ পদ্ধতির একটি বৈকল্পিক with আপনি পাইথন কোড এবং ফলাফলগুলি এখানে পেতে পারেন । সামগ্রিক উপসংহারটি হ'ল কেস স্টেটমেন্টের সাথে বৈকল্পিকটি অন্য দুটি রূপের চেয়ে দ্বিগুণ দ্রুত পরিণত হয়েছে, তবে এর জন্য সঠিক এবং ইনজেকশন-নিরাপদ কোডটি লেখা বেশ শক্ত, তাই আমি ব্যক্তিগতভাবে সহজ পদ্ধতির সাথে লেগে থাকি: লেনদেন ব্যবহার করে।

সম্পাদনা: ফলাফল Dakusan প্রমাণ যে আমার কর্মক্ষমতা হিসেব বেশ বৈধ নয়। আরও উত্তর , আরও বিস্তৃত গবেষণার জন্য দয়া করে এই উত্তরটি দেখুন।


লেনদেন ব্যবহার করে, খুব সুন্দর (এবং সাধারণ) টিপ!
mTorres

আমার টেবিলগুলি ইনোডিবি টাইপ না হলে কী হবে?
TomeeNS

1
এই লেনদেনটির মতো দেখতে কী কী কোনও লিংক সরবরাহ করতে পারে? এবং / অথবা কেস স্টেটমেন্ট সহ বৈকল্পিকের জন্য ইঞ্জেকশন-নিরাপদ কোডের কোড?
ফ্রান্সোইস এম।

1
আমি এই পোস্টে গতি সম্পর্কে প্রদত্ত তথ্য ভুল বলে মনে করি। আমি নীচে একটি পোস্টে এটি সম্পর্কে লিখেছি। stackoverflow.com/questions/3432/multiple-updates-in-mysql/...
Dakusan

1
@ ডাকুসান, দুর্দান্ত উত্তর। আমার ফলাফলগুলি প্রসারিত, মন্তব্য এবং ফিক্স করার জন্য অনেক ধন্যবাদ।
রোমান ইমানকুলভ

72

নিশ্চিত না কেন অন্য কার্যকর বিকল্পটি এখনও উল্লেখ করা হয়নি:

UPDATE my_table m
JOIN (
    SELECT 1 as id, 10 as _col1, 20 as _col2
    UNION ALL
    SELECT 2, 5, 10
    UNION ALL
    SELECT 3, 15, 30
) vals ON m.id = vals.id
SET col1 = _col1, col2 = _col2;

4
এটিই সর্বোত্তম. বিশেষত যদি আপনি অন্য এসকিউএল কোয়েরি থেকে আপডেটের জন্য মানগুলি টানতে থাকি।
v010dya

1
বিশাল পরিমাণে কলাম সহ একটি টেবিলের আপডেটের জন্য এটি দুর্দান্ত ছিল। ভবিষ্যতে আমি সম্ভবত এই ক্যোয়ারীটি অনেক ব্যবহার করব। ধন্যবাদ!
ক্যাস্পার উইলকস

আমি এই ধরণের ক্যোয়ারী চেষ্টা করেছি। কিন্তু রেকর্ডগুলি 30k বাউন্ডারি সার্ভারে পৌঁছে গেলে বন্ধ হয়ে যায়। অন্য কোন সমাধান আছে কি?
ভাভিন চৌহান

এটি দুর্দান্ত দেখাচ্ছে। আমি এটিকে এমন একটি ক্লোজের সাথে সংযুক্ত করার চেষ্টা করব যেখানে প্রাথমিক কীগুলি আপডেট হয় না, তবে পরিবর্তনের জন্য কলামগুলি সনাক্ত করতে ব্যবহৃত হয়।
এনএল-এক্স

@ ভাবিনচৌহান আপনি কি সমস্যা সমাধানের জন্য জয়েন-সিলেক্টের পরিবর্তে অস্থায়ী টেবিলটি ব্যবহার করার চেষ্টা করেছেন?
এনএল-এক্স

41

নীচের সমস্তগুলি ইনোডিবিতে প্রযোজ্য।

আমি অনুভব করি 3 ভিন্ন পদ্ধতির গতি জেনে রাখা গুরুত্বপূর্ণ।

এখানে 3 টি পদ্ধতি রয়েছে:

  1. ইনসার্ট: অনুলিপি কী আপডেটের সাথে সন্নিবেশ করুন
  2. লেনদেন: যেখানে আপনি লেনদেনের মধ্যে প্রতিটি রেকর্ডের জন্য আপডেট করেন
  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).';');
}

1
আপনি এখানে প্রভুর কাজ করছেন;) অনেক প্রশংসা করেছেন।
মরিচ

GoLang এবং PHP এর মধ্যে কিছু পারফরম্যান্স পরীক্ষা করে, মারিয়াডিবিতে 40k সারি ব্যবহার করে, আমি পিএইচপিতে 2 সেকেন্ড এবং গোলাংয়ে 6 সেকেন্ডের বেশি পাচ্ছিলাম .... আচ্ছা, আমাকে সর্বদা বলা হয়েছিল যে পিএইচপি এর চেয়ে দ্রুত গ্লোং চলবে !!! সুতরাং, আমি কীভাবে পারফরম্যান্সটি উন্নত করব তা ভাবতে শুরু করি ... INSERT ব্যবহার করে ... কী কী আপডেটের জন্য ডুপ্লিকেট করলাম ... আমি গোলং-তে 0.74 সেকেন্ড এবং পিএইচপি-তে 0.86 সেকেন্ড পেয়েছি !!!!
দিয়েগো ফ্যাভেরো

1
আমার কোডের বিষয়টি হ'ল সময়কালীন ফলাফলগুলি কঠোরভাবে এসকিউএল স্টেটমেন্টের মধ্যে সীমাবদ্ধ করা, ভাষা বা গ্রন্থাগারগুলির কোড নয়। GoLang এবং পিএইচপি সম্পূর্ণ ভিন্ন জিনিসগুলির জন্য বোঝানো 2 সম্পূর্ণ পৃথক পৃথক ভাষা। পিএইচপি বলতে বোঝায় বেশিরভাগ সীমাবদ্ধ এবং নিষ্ক্রিয় আবর্জনা সংগ্রহ সহ একক থ্রেডে একক রান স্ক্রিপ্টিং পরিবেশের জন্য। GoLang হ'ল আক্রমণাত্মক আবর্জনা সংগ্রহ এবং মাল্টিথ্রেডিং সহ প্রাথমিক ভাষার বৈশিষ্ট্যগুলির একটি হিসাবে দীর্ঘকালীন চলমান সংকলিত অ্যাপ্লিকেশনগুলির জন্য। ভাষার কার্যকারিতা এবং কারণের ক্ষেত্রে এগুলি সবেই আলাদা হতে পারে। [অব্যাহত]
ডাকসান

সুতরাং আপনার পরীক্ষা চালানোর সময়, গতির পরিমাপকে এসকিউএল স্টেটমেন্টের জন্য কঠোরভাবে "ক্যোয়ারী" ফাংশন কলকে সীমাবদ্ধ করার বিষয়টি নিশ্চিত করুন। উত্স কোডের অন্যান্য অংশগুলির তুলনা করা এবং অপ্টিমাইজ করা যা কোয়েরি কলটি কঠোরভাবে নয়, এটি আপেল এবং কমলার তুলনা করার মতো। আপনি যদি নিজের ফলাফলগুলিকে এটিতে সীমাবদ্ধ করেন (স্ট্রিংগুলি পূর্বনির্ধারিত এবং যাওয়ার জন্য প্রস্তুত থাকে) তবে ফলাফলগুলি খুব একই রকম হওয়া উচিত। এই সময়ে যে কোনও পার্থক্য হ'ল ভাষার এসকিউএল লাইব্রেরির দোষ, এবং অগত্যা ভাষা নিজেই। আমার মতে, INSERT অন ডুপ্লিকেট সমাধানটি ছিল এবং সর্বদা সর্বোত্তম বিকল্প হবে Cont [
সূচনা

GoLang দ্রুত হওয়ার বিষয়ে আপনার মন্তব্য হিসাবে, এটি একটি অবিশ্বাস্যরূপে বিস্তৃত বিবৃতি যা এই ভাষাগুলির বিপুল সংখ্যক সংক্ষিপ্ত বিবরণ এবং তাদের নকশাকে বিবেচনা করে না। জাভা একটি ব্যাখ্যামূলক ভাষা, তবে আমি খুঁজে পেয়েছি 15 বছর আগে এটি কিছুটা দৃশ্যে সি এর সাথে প্রায় গতিবেগ করতে পারে (এবং এমনকি কখনও কখনও পরাজিতও হতে পারে) C এবং সি একটি সংকলিত ভাষা এবং এসেম্বলারের পাশাপাশি নিম্নতম স্তরের সিস্টেমের ভাষাগুলির মধ্যে সর্বাধিক সাধারণ। GoLang যা করছে তা আমি সত্যিই পছন্দ করি এবং এটি অবশ্যই খুব সাধারণ সিস্টেমগুলির মধ্যে একটি হয়ে ও অনুকূলিত হওয়ার শক্তি এবং তরলতা পেয়েছে [
কন্টেন্ট

9

অস্থায়ী টেবিল ব্যবহার করুন

// Reorder items
function update_items_tempdb(&$items)
{
    shuffle($items);
    $table_name = uniqid('tmp_test_');
    $sql = "CREATE TEMPORARY TABLE `$table_name` ("
        ."  `id` int(10) unsigned NOT NULL AUTO_INCREMENT"
        .", `position` int(10) unsigned NOT NULL"
        .", PRIMARY KEY (`id`)"
        .") ENGINE = MEMORY";
    query($sql);
    $i = 0;
    $sql = '';
    foreach ($items as &$item)
    {
        $item->position = $i++;
        $sql .= ($sql ? ', ' : '')."({$item->id}, {$item->position})";
    }
    if ($sql)
    {
        query("INSERT INTO `$table_name` (id, position) VALUES $sql");
        $sql = "UPDATE `test`, `$table_name` SET `test`.position = `$table_name`.position"
            ." WHERE `$table_name`.id = `test`.id";
        query($sql);
    }
    query("DROP TABLE `$table_name`");
}


6

কেন কেউ একটি প্রশ্নের একাধিক বিবৃতি উল্লেখ করে না ?

পিএইচপি ইন, আপনি ব্যবহার multi_query mysqli উদাহরণের পদ্ধতি ।

থেকে পিএইচপি ম্যানুয়াল

মাইএসকিউএল বিকল্পভাবে একটি স্টেটমেন্ট স্ট্রিংয়ে একাধিক স্টেটমেন্ট থাকার অনুমতি দেয়। একবারে একাধিক বিবৃতি পাঠানো ক্লায়েন্ট-সার্ভারের রাউন্ড ট্রিপগুলি হ্রাস করে তবে বিশেষ হ্যান্ডলিংয়ের প্রয়োজন।

30,000 কাঁচা আপডেটে অন্যান্য 3 পদ্ধতির সাথে তুলনা করার ফলাফল এখানে। কোডটি এখানে পাওয়া যাবে যা @ ডাকুসানের উত্তরের ভিত্তিতে রয়েছে

লেনদেন: 5.5194580554962
সন্নিবেশ: 0.20669293403625
কেস: 16.474853992462
মাল্টি: 0.0412278175354

আপনি দেখতে পাচ্ছেন যে একাধিক বিবৃতি কোয়েরি সর্বোচ্চ উত্তরের চেয়ে কার্যকর।

আপনি যদি এর মতো ত্রুটি বার্তা পান:

PHP Warning:  Error while sending SET_OPTION packet

আপনার max_allowed_packetমাইএসকিএল কনফিগারেশন ফাইলটি বাড়ানোর দরকার হতে পারে যা আমার মেশিনে রয়েছে /etc/mysql/my.cnfএবং তারপরে মাইএসকিএলডি পুনরায় চালু করতে হবে।


নীচের সমস্ত তুলনা INSERT পরীক্ষার বিরুদ্ধে চালানো হয়। আমি কেবল একই শর্তে পরীক্ষা চালিয়েছি এবং লেনদেন ছাড়াই এটি 300 সারিগুলির 145x ধীর এবং 3000 সারির জন্য 753x ধীর ছিল। আমি মূলত 30,000 সারি দিয়ে শুরু করেছি, তবে আমি নিজেকে লাঞ্চ করতে গিয়ে ফিরে এসেছি এবং এখনও চলছে। এটি পৃথক অনুসন্ধান চালানো এবং পৃথকভাবে ডাটাবেসে প্রতিটি ফ্লাশ করা হাস্যকর ব্যয়বহুল হিসাবে বিবেচনা করে। বিশেষ করে প্রতিরূপ। যদিও লেনদেন চালু করা বড় পার্থক্য করে। 3,000 সারি এটা গ্রহণ 1.5x আরো এবং 30,000 সারি এ 2.34x । [অব্যাহত]
ডাকসান

তবে আপনি এটি দ্রুত (লেনদেন সহ) সম্পর্কে ঠিক বলেছেন। 3,000 এবং 30,000 উভয় সারিতে উভয়ই INSERT পদ্ধতি ব্যতীত দ্রুত ছিল। কোনও বিশেষ মাইএসকিউএল এপিআই কল থাকলেও 30,000 প্রশ্নের চেয়ে 1 টি ক্যোয়ারী চালিয়ে আপনি আরও ভাল ফলাফল পেতে চলেছেন এমন কোনও উপায় নেই। কেবল 300 টি সারি চালানো, এটি অন্যান্য সমস্ত পদ্ধতির তুলনায় খুব দ্রুত ছিল (আমার আশ্চর্যজনক), যা CASE পদ্ধতি হিসাবে একই গ্রাফ বক্ররেখার অনুসরণ করে। এটি দ্রুত হওয়া 2 উপায় দ্বারা ব্যাখ্যা করা যেতে পারে। প্রথমটি হচ্ছে যে INSERT পদ্ধতিটি মূলত সর্বদা 2 সারি সন্নিবেশ করে কারণ "অন
ডুপ্লিকেট

আপডেট "উভয়ই" INSERT "এবং" আপডেট "তৈরি করে The অপরটি হ'ল এটি যে এসকিউএল প্রসেসরে কম কাজ করছে কেবলমাত্র 1 টি সারি সম্পাদনা করার জন্য সূচীদর্শনগুলির কারণে। তবে আপনার অতিরিক্ত পরীক্ষাটি
দৃ looks়

আমি ল্যাপের জন্য একটি ত্রুটিটি সংশোধন করতে এক টেবিলে একসাথে 300 আপডেট করছি যা 41 সেকেন্ড সময় নিয়েছিল took একই আপডেটের ক্যোয়ারিকে একের মধ্যে রেখে $mysqli->multi_query($sql)"0" সেকেন্ড সময় নেয়। তবে পরবর্তী প্রশ্নগুলি ব্যর্থ হয়েছে, যার ফলে এটি এটিকে একটি পৃথক "প্রোগ্রাম" বানিয়েছে।
ক্রিস কে

ধন্যবাদ। একাধিক কোয়েরি ব্যবহার করে এক মিনিটে প্রায় 5 কে সারি (আরও পরীক্ষা করা হয়নি) আপডেট করতে সক্ষম হয়েছিল। কেউ একটি PDO সমাধান খুঁজছে এমন: stackoverflow.com/questions/6346674/...
স্কোফিল্ডের

3

'মাল্টি স্টেটমেন্ট' নামে পরিচিত এমন একটি সেটিংস রয়েছে যা মাইএসকিউএল'র 'সুরক্ষা ব্যবস্থা' অক্ষম করে (একাধিক) ইনজেকশন কমান্ড প্রতিরোধ করতে প্রয়োগ করা হয়। মাইএসকিউএল এর 'উজ্জ্বল' বাস্তবায়নের সাধারণ, এটি ব্যবহারকারীকে দক্ষ জিজ্ঞাসা করতে বাধা দেয়।

এখানে ( http://dev.mysql.com/doc/refman/5.1/en/mysql-set-server-option.html ) সেটিংসের সি বাস্তবায়নের বিষয়ে কিছু তথ্য।

আপনি যদি পিএইচপি ব্যবহার করে থাকেন তবে আপনি বহু বিবৃতি দেওয়ার জন্য মাইএসকিলি ব্যবহার করতে পারেন (আমার মনে হয় পিএইচপি কিছুক্ষণের জন্য মাইসকিলি দিয়ে এসেছে)

$con = new mysqli('localhost','user1','password','my_database');
$query = "Update MyTable SET col1='some value' WHERE id=1 LIMIT 1;";
$query .= "UPDATE MyTable SET col1='other value' WHERE id=2 LIMIT 1;";
//etc
$con->multi_query($query);
$con->close();

আশা করি এইটি কাজ করবে.


4
এটি আলাদাভাবে কোয়েরি প্রেরণের মতোই। পার্থক্যটি হ'ল আপনি এটি সমস্ত একটি নেটওয়ার্ক প্যাকেটে প্রেরণ করেন তবে ইউপিডিয়াসগুলি পৃথক অনুসন্ধান হিসাবে এখনও প্রক্রিয়া করা হবে। এগুলি একটি লেনদেনে মুড়ে ফেলা ভাল, তারপরে পরিবর্তনগুলি একবারে টেবিলের কাছে চলে আসবে।
Marki555

3
কীভাবে সেগুলি একটি লেনদেনে গুটিয়ে রাখা যায়? দয়া করে আমাদের দেখান
TomeeNS

@ TomeeNS mysqli::begin_transaction(..)ক্যোয়ারী প্রেরণের আগে এবং mysql::commit(..)পরে ব্যবহার করুন । অথবা ক্যোয়ারীতে নিজেই START TRANSACTIONপ্রথম এবং COMMITশেষ বিবৃতি হিসাবে ব্যবহার করুন ।
জুহা পালোমকি

3

আপনি যে আইডিটি sertোকাতে চান তা দিতে একই টেবিলটিকে আপনি উপনাম করতে পারেন (আপনি যদি সারি-সারি সারি আপডেট করে থাকেন:

UPDATE table1 tab1, table1 tab2 -- alias references the same table
SET 
col1 = 1
,col2 = 2
. . . 
WHERE 
tab1.id = tab2.id;

অতিরিক্তভাবে, এটি স্পষ্ট বলে মনে হয় যে আপনি অন্যান্য টেবিলগুলি থেকেও আপডেট করতে পারেন। এই ক্ষেত্রে, আপডেটটি আপনি নির্দিষ্ট করে দিচ্ছেন এমন সারণী থেকে ডেটা দেবে, এটি "নির্বাচন" বিবৃতি হিসাবে দ্বিগুণ। আপনি আপনার ক্যোয়ারিতে স্পষ্টভাবে আপডেটের মানগুলি উল্লেখ করছেন যাতে দ্বিতীয় টেবিলটি প্রভাবিত হয় না।


2

আপনি আপডেটগুলিতে যোগদানের ক্ষেত্রেও আগ্রহী হতে পারেন, এটিও সম্ভব।

Update someTable Set someValue = 4 From someTable s Inner Join anotherTable a on s.id = a.id Where a.id = 4
-- Only updates someValue in someTable who has a foreign key on anotherTable with a value of 4.

সম্পাদনা: আপনি যে মানগুলি আপডেট করছেন তা যদি ডাটাবেসের অন্য কোথাও থেকে না আসে, আপনাকে একাধিক আপডেট ক্যোয়ারী জারি করতে হবে।


1

এবং এখন সহজ উপায়

update speed m,
    (select 1 as id, 20 as speed union
     select 2 as id, 30 as speed union
     select 99 as id, 10 as speed
        ) t
set m.speed = t.speed where t.id=m.id

-1

ব্যবহার

REPLACE INTO`table` VALUES (`id`,`col1`,`col2`) VALUES
(1,6,1),(2,2,3),(3,9,5),(4,16,8);

দয়া করে নোট করুন:

  • আইডি একটি প্রাথমিক অনন্য কী হতে হবে
  • আপনি যদি টেবিলটি রেফারেন্স করতে বিদেশী কীগুলি ব্যবহার করেন তবে REPLACE এর পরে সন্নিবেশগুলি মুছে ফেলা হয়, যাতে এটি ত্রুটির কারণ হতে পারে

-3

নিম্নলিখিতটি একটি সারণীতে সমস্ত সারি আপডেট করবে

Update Table Set
Column1 = 'New Value'

পরেরটি সমস্ত সারি আপডেট করবে যেখানে কলাম 2 এর মান 5 এর বেশি

Update Table Set
Column1 = 'New Value'
Where
Column2 > 5

একাধিক টেবিল আপডেট করার সমস্ত আনকন্টেকের উদাহরণ রয়েছে

UPDATE table1, table2 SET
table1.col1 = 'value',
table2.col1 = 'value'
WHERE
table1.col3 = '567'
AND table2.col6='567'

-3

হ্যাঁ .. এটি ডুপ্লিকেট কী আপডেটের স্কেল স্টেটমেন্টে ইনসার্ট ব্যবহার করা সম্ভব .. সিনট্যাক্স: সারণি নাম অন্তর্ভুক্ত করুন (ক, খ, সি) ভ্যালু (1,2,3), (4,5,6) নম্বরের কী আপডেট করুন a = মান (ক) খ = মান (খ), গ = মান (গ)


-5
UPDATE tableName SET col1='000' WHERE id='3' OR id='5'

এটি আপনি যা খুঁজছেন তা অর্জন করা উচিত। আরও আইডির যোগ করুন। আমি এটি পরীক্ষা করেছি।


-7
UPDATE `your_table` SET 

`something` = IF(`id`="1","new_value1",`something`), `smth2` = IF(`id`="1", "nv1",`smth2`),
`something` = IF(`id`="2","new_value2",`something`), `smth2` = IF(`id`="2", "nv2",`smth2`),
`something` = IF(`id`="4","new_value3",`something`), `smth2` = IF(`id`="4", "nv3",`smth2`),
`something` = IF(`id`="6","new_value4",`something`), `smth2` = IF(`id`="6", "nv4",`smth2`),
`something` = IF(`id`="3","new_value5",`something`), `smth2` = IF(`id`="3", "nv5",`smth2`),
`something` = IF(`id`="5","new_value6",`something`), `smth2` = IF(`id`="5", "nv6",`smth2`) 

// আপনি কেবল এটি পিএইচপি পছন্দ করেন

$q = 'UPDATE `your_table` SET ';

foreach($data as $dat){

  $q .= '

       `something` = IF(`id`="'.$dat->id.'","'.$dat->value.'",`something`), 
       `smth2` = IF(`id`="'.$dat->id.'", "'.$dat->value2.'",`smth2`),';

}

$q = substr($q,0,-1);

সুতরাং আপনি একটি ক্যোয়ারী সহ গর্ত টেবিল আপডেট করতে পারেন


আমি ডাউনওয়েট করি নি, তবে আমার মনে হয় আপত্তিটি সেটটি করার বিষয়ে, যখন এটির প্রয়োজন নেই (এবং আপনি এখনও এটি করছেন, যখন আপনি সেট somethingকরছেন something)
v010dya
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.