পিডিওর ক্যোয়ারী বনাম এক্সিকিউট করুন


129

তারা দুজনেই কি একই কাজ করছে, কেবল ভিন্নভাবে?

এর prepareমধ্যে ব্যবহারের পাশাপাশি কি কোনও পার্থক্য রয়েছে?

$sth = $db->query("SELECT * FROM table");
$result = $sth->fetchAll();

এবং

$sth = $db->prepare("SELECT * FROM table");
$sth->execute();
$result = $sth->fetchAll();

?

উত্তর:


145

query একটি স্ট্যান্ডার্ড এসকিউএল স্টেটমেন্ট চালায় এবং এসকিউএল ইনজেকশন এবং অন্যান্য সমস্যাগুলি এড়াতে আপনাকে সমস্ত ডেটা সঠিকভাবে এড়িয়ে চলতে হবে।

executeএকটি প্রস্তুত বিবৃতি চালায় যা আপনাকে পরামিতিগুলি পালাতে বা উদ্ধৃতি দেওয়ার প্রয়োজন এড়াতে প্যারামিটারগুলিকে আবদ্ধ করতে দেয়। executeআপনি যদি একাধিকবার কোনও কোয়েরি পুনরাবৃত্তি করে থাকেন তবে আরও ভাল সম্পাদন করবে। প্রস্তুত বিবৃতি উদাহরণ:

$sth = $dbh->prepare('SELECT name, colour, calories FROM fruit
    WHERE calories < :calories AND colour = :colour');
$sth->bindParam(':calories', $calories);
$sth->bindParam(':colour', $colour);
$sth->execute();
// $calories or $color do not need to be escaped or quoted since the
//    data is separated from the query

সর্বোত্তম অনুশীলন হ'ল প্রস্তুত বিবৃতি এবং executeবর্ধিত সুরক্ষা রক্ষা করা

আরও দেখুন: পিডিও কি এসকিউএল ইঞ্জেকশন প্রতিরোধের জন্য বিবৃতি প্রস্তুত?


লিঙ্কটি ইতিমধ্যে মন্তব্যে সমালোচিত, বেশ বোকা উত্তরের সাথে প্রশ্নকে বাড়ে।
আপনার সাধারণ জ্ঞান

সুতরাং আপনি যদি একটি প্রস্তুতি ব্যবহার করেন তবে ইঞ্জেকশন বন্ধ করার মতো : calories ধরণের সমতুল্য mysql_real_escape_string()নাকি আপনার কেবল $sth->bindParam(':calories', $calories);সুরক্ষা বাড়ানোর চেয়ে আরও কিছু দরকার ?
ড্যান

কেন queryএকটি ফিরতি PDOStatement , একটি পরিবর্তে bool, মত execute?
লিও

1
একাধিকবার একটি কোয়েরি পুনরাবৃত্তি করা সমস্ত PDO ড্রাইভারের সাথে কাজ করে না
জেফ পেকেট

47

না, তারা এক নয়। এটি সরবরাহ করে এমন ক্লায়েন্ট-সাইডে পালিয়ে যাওয়া বাদ দিয়ে, প্রস্তুত বিবৃতিটি একবার সার্ভার-সাইডে সংকলিত হয় এবং তারপরে প্রতিটি নির্বাহের সময় বিভিন্ন পরামিতি পাস করা যায় । যার অর্থ আপনি করতে পারেন:

$sth = $db->prepare("SELECT * FROM table WHERE foo = ?");
$sth->execute(array(1));
$results = $sth->fetchAll(PDO::FETCH_ASSOC);

$sth->execute(array(2));
$results = $sth->fetchAll(PDO::FETCH_ASSOC);

তারা সাধারণত আপনাকে একটি পারফরম্যান্স উন্নতি দেবে, যদিও সামান্য স্কেলে তা লক্ষণীয় নয়। প্রস্তুত বিবৃতি (মাইএসকিউএল সংস্করণ) সম্পর্কে আরও পড়ুন


আপনি যেভাবে ব্যাখ্যা করেছেন এটি কেন দ্রুত হবে তা আমার পছন্দ।
টিমফ্রেলি


3

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

একটি ক্ষেত্রে, আমি খুঁজে পেয়েছি যে queryআমার উদ্দেশ্যগুলির জন্য দ্রুত কাজ করেছে কারণ আমি এমএস এসকিউএল সার্ভারের জন্য দুর্বল সমর্থিত মাইক্রোসফ্ট ওডিবিসি ড্রাইভারের সাথে পিএইচপি 7 চলমান একটি উবুন্টু লিনাক্স বক্স থেকে নির্ভরযোগ্য ডেটা স্থানান্তর করেছি ।

আমি এই প্রশ্নে পৌঁছেছি কারণ একটি ইটিএল-এর জন্য আমার একটি দীর্ঘ চলমান স্ক্রিপ্ট ছিল যা আমি গতির জন্য চেপে ধরার চেষ্টা করছিলাম। এটি আমার কাছে স্বজ্ঞাত বলে মনে হয়েছিল যা এর queryচেয়ে দ্রুততর হতে পারে prepareএবং executeকারণ এটি দুটিয়ের পরিবর্তে কেবল একটি ফাংশনকে ডেকেছিল। প্যারামিটার বাইন্ডিং অপারেশন দুর্দান্ত সুরক্ষা সরবরাহ করে তবে এটি ব্যয়বহুল এবং সম্ভবত অপ্রয়োজনীয় হলে এড়ানো সম্ভব।

একটি দম্পতি বিরল অবস্থা দেওয়া :

  1. আপনি যদি কোনও প্রস্তুত বিবৃতি পুনরায় ব্যবহার করতে না পারেন কারণ এটি মাইক্রোসফ্ট ওডিবিসি ড্রাইভার দ্বারা সমর্থিত নয়

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

  3. PDO::lastInsertId মাইক্রোসফ্ট ওডিবিসি ড্রাইভার সমর্থন করে না।

আমি আমার পরিবেশ পরীক্ষা করার জন্য একটি পদ্ধতি ব্যবহার করেছি এবং আশা করি আপনি এটি বা আপনার আরও ভাল কিছু প্রতিলিপি করতে পারেন:

শুরু করতে, আমি মাইক্রোসফ্ট এসকিউএল সার্ভারে একটি প্রাথমিক টেবিল তৈরি করেছি

CREATE TABLE performancetest (
    sid INT IDENTITY PRIMARY KEY,
    id INT,
    val VARCHAR(100)
);

পারফরম্যান্স মেট্রিকের জন্য এখন একটি প্রাথমিক সময়সীমা পরীক্ষা।

$logs = [];

$test = function (String $type, Int $count = 3000) use ($pdo, &$logs) {
    $start = microtime(true);
    $i = 0;
    while ($i < $count) {
        $sql = "INSERT INTO performancetest (id, val) OUTPUT INSERTED.sid VALUES ($i,'value $i')";
        if ($type === 'query') {
            $smt = $pdo->query($sql);
        } else {
            $smt = $pdo->prepare($sql);
            $smt ->execute();
        }
        $sid = $smt->fetch(PDO::FETCH_ASSOC)['sid'];
        $i++;
    }
    $total = (microtime(true) - $start);
    $logs[$type] []= $total;
    echo "$total $type\n";
};

$trials = 15;
$i = 0;
while ($i < $trials) {
    if (random_int(0,1) === 0) {
        $test('query');
    } else {
        $test('prepare');
    }
    $i++;
}

foreach ($logs as $type => $log) {
    $total = 0;
    foreach ($log as $record) {
        $total += $record;
    }
    $count = count($log);
    echo "($count) $type Average: ".$total/$count.PHP_EOL;
}

আমি একাধিক পৃথক পরীক্ষার সাথে খেলেছি এবং আমার নির্দিষ্ট পরিবেশে গণনা করেছি এবং ধারাবাহিকভাবে 20-30% এর queryচেয়ে দ্রুত ফলাফল পেয়েছি prepare/ এর সাথেexecute

5.8128969669342 প্রস্তুত
5.8688418865204 প্রস্তুত
4.2948560714722 ক্যোয়ারী
4.9533629417419 ক্যোয়ারী
5.9051351547241 প্রস্তুত
4,332102060318 ক্যোয়ারী
5,9672858715057 প্রস্তুত
5,0667371749878 ক্যোয়ারী
3,8260300159454 ক্যোয়ারী
4,0791549682617 ক্যোয়ারী
4,3775160312653 ক্যোয়ারী
3,6910600662231 ক্যোয়ারী
5,2708210945129 প্রস্তুত
6,2671611309052 প্রস্তুত
7,3791449069977 প্রস্তুত
(7) গড় প্রস্তুত করুন: 6.0673267160143
(8) ক্যোয়ারী গড়: 4,3276024162769

এই পরীক্ষাটি অন্য পরিবেশে যেমন MySQL এর সাথে তুলনা করে তা দেখতে আমি আগ্রহী cur


"অভিজ্ঞতাবাদী প্রমাণ" (বা বরং কৃত্রিম পরীক্ষাগুলি) নিয়ে সমস্যা যে তারা আপনার (অজানা) নির্দিষ্ট অবস্থার প্রতিফলন করে এবং অন্য কারও পক্ষে পৃথক হতে পারে, আসল বিশ্ব অভিজ্ঞতা অভিজ্ঞতা প্রমাণ করা যাক। তবুও কিছু লোক এটিকে গুরুত্বের সাথে গ্রহণ করবে এবং শব্দটি আরও ছড়িয়ে দেবে।
আপনার সাধারণ জ্ঞান

@ আপনার কমারসেন্স আমি সম্পূর্ণ সম্মত এবং আপনার মতামতের জন্য ধন্যবাদ কারণ আমি ভেবেছিলাম এটি আমার সাহসী বিরল পরিস্থিতি থেকে পরিষ্কার ছিল। আমি সন্দেহের একটি স্বাস্থ্যকর ডোজ ধরেছি, তবে ভুলে যাচ্ছি এটি সুস্পষ্ট নয়। দয়া করে আমার সংশোধিত আমার উত্তরটি দেখুন এবং কীভাবে এটি উন্নত করা যায় তা আমাকে জানান।
জেফ পেকেট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.