คำตอบของ Gileanดีมาก แต่ฉันแค่อยากจะเพิ่มว่าบางครั้งมีข้อยกเว้นที่หายากสำหรับแนวทางปฏิบัติที่ดีที่สุดและคุณอาจต้องการทดสอบสภาพแวดล้อมของคุณทั้งสองวิธีเพื่อดูว่าอะไรจะได้ผลดีที่สุด
ในกรณีหนึ่งผมพบว่าquery
ทำงานได้เร็วขึ้นเพื่อวัตถุประสงค์ของฉันเพราะฉันเป็นจำนวนมากการถ่ายโอนข้อมูลที่เชื่อถือได้จากกล่อง Ubuntu Linux ทำงาน PHP7 กับการสนับสนุนไม่ดีควบคุม Microsoft ODBC สำหรับ MS SQL Server
ฉันมาถึงคำถามนี้เพราะฉันมีสคริปต์ที่ใช้งานยาวนานสำหรับETLซึ่งฉันพยายามบีบเพื่อความเร็ว ดูเหมือนจะใช้งานง่ายสำหรับฉันที่query
อาจเร็วกว่าprepare
& execute
เพราะมันเรียกใช้ฟังก์ชันเดียวแทนที่จะเป็นสองฟังก์ชัน การดำเนินการรวมพารามิเตอร์ให้การป้องกันที่ดีเยี่ยม แต่อาจมีราคาแพงและอาจหลีกเลี่ยงได้หากไม่จำเป็น
มีเงื่อนไขที่หายากสองสามข้อ :
ถ้าคุณไม่สามารถนำมาใช้งบเตรียมเพราะมันไม่ได้รับการสนับสนุนโดยควบคุม Microsoft ODBC
หากคุณไม่กังวลเกี่ยวกับการทำความสะอาดอินพุตและการหลบหนีง่ายๆเป็นที่ยอมรับได้ นี้อาจจะเป็นกรณีนี้เพราะมีผลผูกพันประเภทข้อมูลบางอย่างที่ไม่ได้รับการสนับสนุนโดยควบคุม Microsoft ODBC
PDO::lastInsertId
ไม่ได้รับการสนับสนุนโดยโปรแกรมควบคุม Microsoft ODBC
นี่เป็นวิธีการที่ฉันใช้ในการทดสอบสภาพแวดล้อมของฉันและหวังว่าคุณจะสามารถทำซ้ำหรือสิ่งที่ดีกว่าในของคุณได้:
ในการเริ่มต้นฉันได้สร้างตารางพื้นฐานใน Microsoft SQL Server
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 อย่างไร