2013-01-04 9 views
7

दिखाता है कि यहां एक सरल परीक्षण है जिसे मैं प्रदर्शन दंड का त्वरित विचार प्राप्त करने के लिए चला गया था, जिसे मैं सीधे क्वेरी का उपयोग करके MySQL PDO तैयार कथन बनाम उपयोग करने के लिए भुगतान करता हूं। व्यक्ति तालिका में 2801 पंक्तियां हैं। MySQL संस्करण 5.5.28 और PHP संस्करण 5.3.15। वेनिला इंस्टॉलेशन, जो भी डिफ़ॉल्ट पैरामीटर हैं। टेस्ट 8 जीबी के साथ आईमैक पर चलते हैं।MySQL पीडीओ क्वेरी से तेज़ी से तैयार है? यही सरल परीक्षण

query: 21.010436058044 

prepare/execute: 20.74036192894 

जिस पर सभी पर कोई जुर्माना नहीं दिखाता है:

$pdo = new PDO('mysql:host=localhost;dbname=cwadb_local', 'root', ""); 
$start = microtime(true); 
for ($i = 0; $i < 200; $i++) { 
    $pdo->query("select * from person where name_last = 'smith' or true"); 
} 
echo "<p>query: " . (microtime(true) - $start); 

$start = microtime(true); 
for ($i = 0; $i < 200; $i++) { 
    $stmt = $pdo->prepare("select * from person where name_last = :last or true"); 
    $stmt->execute(array('last' => 'smith')); 
} 
echo "<p>prepare/execute: " . (microtime(true) - $start); 

और इस उत्पादन किया गया था। संभावनाएं:

  • तैयार कथन का कैशिंग वास्तव में काम कर रहा है। (नोटिस मैंने लूप के अंदर तैयार फ़ंक्शन रखा है।)

  • यह एक फर्जी परीक्षण है क्योंकि यह बहुत आसान है।

  • कोई सैद्धांतिक कारण नहीं है कि क्यों तैयार/निष्पादन धीमा होना चाहिए, और निरंतर आलोचनाओं से थक गए, MySQL/PDO/PHP डेवलपर्स ने हमें सभी को चुप रहने के प्रयास में तेज़ी से काम करने के लिए अतिरिक्त मेहनत की है। ।

  • अन्य?

यह कई बार कहा गया है कि तैयार बयान का उपयोग कर (mysqli उन्हें नहीं है) क्वेरी का उपयोग और, पीडीओ में नामित मानकों के साथ, मानकों के साथ काम कर बहुत सुविधाजनक है की तुलना में अधिक सुरक्षित है। लेकिन, यह अक्सर ध्यान दिया जाता है कि प्रत्येक बार निष्पादित होने पर कथन तैयार होने पर प्रदर्शन दंड होता है।

तो, क्या कोई मेरे परीक्षण के विपरीत कुछ परीक्षणों की आपूर्ति कर सकता है? या, क्या हम अभी स्वीकार करेंगे कि तैयार वक्तव्यों का उपयोग न करने का कोई कारण नहीं है?

+2

1) बहुत बढ़िया 2) हां 3) "कौन परवाह करता है?" - तैयार बयान का प्रयोग करें। –

+1

बस इसके लिए, अधिक प्रश्नों के साथ इसे फिर से चलाने का प्रयास करें और ऑर्डर को स्वैप करने का प्रयास करें (पहले तैयार)। – Supericy

+0

मैंने सोचा होगा कि तैयार कथन सीधे प्रश्नों की तुलना में _faster_ होने की उम्मीद है, इस आधार पर कि तैयार कथन में एसक्यूएल हर बार समान होता है। यह क्वेरी सर्वर को डेटाबेस सर्वर में कैश करने की अनुमति देता है, जो संभव नहीं है यदि आप निरंतर गैर-तैयार 'WHERE' खंड बदल रहे हैं। – halfer

उत्तर

4

मैं अपनी कार्यप्रणाली के साथ कुछ मुद्दों है:

  1. जब तक वहाँ बिल्कुल कुछ नहीं स्क्रिप्ट है, जो की संभावना नहीं है के रूप में एक ही समय में सर्वर पर चल रहा है, अपने मौलिक टाइमर सीपीयू की सनक के अधीन है शेड्यूलिंग। इसका पता लगाने, दो अलग स्क्रिप्ट लिखने और उन्हें प्रयोग * nix के time आदेश, यानी चलाने के लिए: क्वेरी कैशिंग mySQL के कारण time php myscript.php
  2. स्क्रिप्ट के क्रम एक ही परिणाम उत्पन्न कर सकता है पीछे।
  3. एक परीक्षण प्रत्येक निदान नहीं करता है। प्रत्येक स्क्रिप्ट को कुछ सौ, या कुछ हज़ार, बार चलाने की कोशिश करें और फिर परिणाम को अधिक अच्छी तरह से गोल करने के परिणाम प्राप्त करें।

लेकिन वहां अभी भी कोई कारण नहीं है एक गैर स्थिर क्वेरी के मामले में तैयार बयान का उपयोग नहीं करने के लिए जब तक आप कड़ाई से एसक्यूएल इंजेक्शन की संभावना होने के लिए और समय की अपनी आदानों की सभी सब अभी भी मान्य की तरह है।

+0

और उसके बाद # 4 जारी करें: * अंदर * लूप तैयार करना मूर्खतापूर्ण है। – Charles

+2

चूंकि यह तैयार/निष्पादित करने की लागत का एक समय परीक्षण है, लूप में तैयार नहीं होने से परीक्षण को अमान्य कर दिया जाएगा। (यह एक समय परीक्षण है, कार्यक्रमों को लिखने के लिए नुस्खा नहीं है!) –

10

उल्लेख करने के लिए एक छोटी सी चीज है। डिफ़ॉल्ट रूप से, पीडीओ बस तैयार बयान अनुकरण।
और जब अनुकरण मोड में, यह वास्तव में एक सिंगल स्टेटमेंट :)

तो, सब से पहले की तैयारी के बिना वही पुरानी क्वेरी चलाता है,

$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE); 

पर वास्तविक रूप से तैयार बयान चालू करने के लिए।

यह बस के रूप में अक्सर उल्लेख किया है निष्पादन दंड

एक और छोटी बात का उल्लेख नहीं है यह है कि।
अफसोस की बात है, दुनिया में बहुत कम वास्तविक ज्ञान हैं। और विशेष रूप से क्यू & की दुनिया में एक साइट। लोग जो जानकारी पढ़ चुके थे उसे दोहराते हैं और उचित पाते हैं। सबूत के लिए या यहां तक ​​कि हाथों को डाले बिना भी परीक्षण किए बिना। इसलिए, "अक्सर ध्यान दिया गया" को विश्वसनीय स्रोत के रूप में नहीं माना जाना चाहिए।

इस मामले पर वापस जाएं: हालांकि कुछ जुर्माना होना चाहिए, यह अधिकतर समय में महत्वहीन होना चाहिए। यदि यह है - आपको अपने सिस्टम को ट्यून करना होगा।

वैसे भी, इम्यूलेशन मोड में आपको यह "तेज़" और सुरक्षित दोनों मिला।

अद्यतन
खैर, मेरी डेटा पर अपने परीक्षण चलाने के बाद, मैं कहता हूँ के लिए कुछ अपने डेटाबेस के साथ कुछ गड़बड़ है, तो आप एक बड़े डेटासेट पर 3 बार फर्क नहीं है मिल गया है।

एक बिजली प्रश्न के लिए

select title from Board where id = 1 

परिणाम हैं

emulation on  off 
query  0.07 0.130 
prepare 0.075 0.145 

जबकि काफी भारी क्वेरी के लिए

select title from Board where id > 1 

परिणाम हैं

emulation on  off 
query  0.96 0.96 
prepare 0.96 1.00 

तो, जैसा कि हम देख सकते हैं, एक बड़े डेटासेट पर अंतर अनजान हो जाता है।

बिजली की क्वेरी के लिए कुछ अंतर है, लेकिन, क्योंकि यह दूसरे के केवल 0,0003 वें गुट (एक प्रश्न के लिए) लेता है - मैं कहूंगा कि यह "उदासीनता" शब्द के लिए एक आदर्श उदाहरण है।

क्वेरी()/तैयार() के बीच के बराबर परिणामों के लिए - मेरे पास केवल एक विचार है - पीडीओ सभी प्रश्नों के लिए तैयार/निष्पादित करता है, यहां तक ​​कि बिना बाइंडिंग के।

अब एन्कोडिंग समस्या के लिए।

हां, अजीब जीबीके समस्या पीडीओ को पहले 5.3.3 के संस्करणों के लिए प्रभावित करती है। इन संस्करणों में उचित एन्कोडिंग सेट करने का कोई तरीका नहीं था और अपरिहार्य कमजोर (इम्यूलेशन मोड में) थे। लेकिन चूंकि 5.3.3 पीडीओ डीएसएन में एन्कोडिंग सेट करने का समर्थन करता है, और अब सब कुछ ठीक है।
mysqli के लिए एक ही (अभेद्य) परिणाम के साथ इस उद्देश्य के लिए mysqli_set_charset() का उपयोग करना होगा।

mysqli पर आधारित मेरी अपनी कक्षा में, मैं अपने प्लेसहोल्डर कार्यान्वयन का उपयोग कर रहा हूं और कोई भी तैयार कथन का उपयोग नहीं कर रहा हूं। प्रदर्शन कारणों के लिए नहीं बल्कि बेहतर विश्वसनीयता के लिए।

+0

बहुत अच्छा बिंदु। जब मैं इसे बंद कर देता हूं, तो वे समय के लगभग एक तिहाई तक गिर जाते हैं। लेकिन ... यह तैयार और तैयार किए गए दोनों मामलों के बारे में सच है। हालांकि, आदेश का आदान-प्रदान किया जाता है: बालों को तेजी से तैयार करने के बजाय, अब यह एक बाल धीमा है। (सड़क पर शब्द यह है कि तैयार किया गया है काफी धीमा है, इसलिए मैं बार-बार कॉल करता हूं - 7.5 सेकंड बनाम 7.3 सेकंड 200 पुनरावृत्तियों के लिए - एक टाई।) –

+0

अनुकरण के बारे में प्रश्न: एक समस्या real_escape_string फ़ंक्शन, भले ही सावधानीपूर्वक उपयोग किया जाता है, यह है कि अजीब चरित्र एन्कोडिंग समस्याएं अभी भी सुरक्षा छेद में हो सकती हैं। (यह कुछ मौकों पर यहां पोस्ट किया गया है।) क्या तैयार बयानों का पीडीओ अनुकरण इसलिए पूरी तरह बुलेट प्रूफ है, या यह real_escape_string (mysqli) या उद्धरण (पीडीओ) का उपयोग करने से बेहतर या बुरा नहीं है? –

+0

MySQL का संस्करण क्या है जिसके खिलाफ आपने अपना परीक्षण चलाया? – meze

संबंधित मुद्दे