• 1 رای - 5 میانگین
  • 1
  • 2
  • 3
  • 4
  • 5
تفاوت بین mysql_query() و mysql_unbuffered_query()
#1
سلام بر همگی، Heart

سطح مقاله: حرفه ای

تا الآن خود من همه جوره پای ثابت استفاده از mysql_query() بودم. ولی حالا با خواهرش اشنا شدم ( mysql_unbuffered_query() ) که قطعا به دلیل ژنتیکی تفاوت هایی باهم دارن Big Grin

امروز این رو مورد بحث میخوام قرار بدم. از وقتی که به این انجمن اومدم کسی در موردش حرفی نزده (من ندیدم) حالا من میگم ببین چند نفر اظهار نظر میکنن. میدونستن و حرفی نزدن Cool

شروع میکنیم...
با mysql_query() آشنا هستید. ولی وقتی اون رو در برابر mysql_unbuffered_query() میگذاریم تفاوت ها خودشون رو نمایان میکنن.
اول با mysql_query() شروع میکنم. اگر کوئری ما SELECT و صحیح باشه داده ها در بافر روی سرور قرار میگیرن. واسه اینکه با داده ها کار کنید باید حتما با تابعی مثل mysql_fetch_row() اون رو واکشی کنیم.

در حالی که واکشی داده ها با تابع mysql_unbuffered_query() خط به خط پس از اینکه بدست میان هست. این به این معنیه که یه مرحله کمتر صورت میگیره نسبت به mysql_query() به عبارت دیگه نیازی به صدا زدن داده از بافر نیست.

در مواقعی که کوئری سنگینی داری mysql_unbuffered_query() کارایی سریع تری داره و حافظه کمتری رو هم اشغال میکنه.

یه تفاوت دیگه که وقتی از mysql_unbuffered_query() استفاده میکنید تابع mysql_num_rows() جواب نمیده چون واقعا نمیشه تشخیص داد چه مقدار نتیجه در مجموعه هست.

یه سوال جالب، چطور mysql_num_rows() تشخیص میده که چه تعداد نتیجه mysql_query() بر میگردونه؟
و پاسخش، mysql_query() کوئری رو اجرا، واکشی و بافر میکنه در نتیجه مجموعه ای کامل از نتایج رو خواهد داشت. حال mysql_num_rows() دسترسی به تمام ردیف ها داره و میتونه تعداد درست رو برگردونه.

مطرح کردن این مسائل ممکنه شمارو گیج کرده باشه. گاهی طرح یک سوال در فهم بهتر موضوع کمک میکنه. پس یه سوال از خودم می پرسم. « اما حالا اگه من ردیف های زیادی داشته باشم و نخوام صبر کنم تا کار واکشی MySQL تموم بشه چیکار کنم؟ »
و پاسخ همون mysql_unbuffered_query() هست.

در جای دیگه اینطوری توضیح داده شده، کار این تابع اینطوریه، کوئری رو اجرا میکنه و اشاره گر منبع (resource pointing) به نتیجه کوئری رو تا وقتی که هنوز MySQL داره کار میکنه بر میگردونه. به این معنی که میتونیم شروع به خوندن کنیم قبل اینکه کوئری به پایان برسه.

در استفاده از mysql_query() این دو تا عیب مشهوده:
1. اینکه PHP مجبوره تا پایان اجرای کوئری و برگشت دادنش صبر کنه.
2. برای اینکه همه نتایج رو یکجا به PHP برگردونیم، همه داده ها باید در RAM نگهداری بشن. بنابراین اگر 100 مگابایت داده برای برگشت داشته باشیم، متغیر پی اچ پی باید تمام اون 100 مگابایت رو نگه داره.

حالا بپردازیم به مزایای mysql_unbuffered_query()
1. اینکه اسکریپت پی اچ پی بلافاصله میتونه نتایج رو تجزیه کنه.
2. فقط یک ردیف در یک زمان نیاز به نگهداری در RAM داره.

**دقت داشته باشید که در ظاهر فرقی با هم ندارن این دو تابع.

قبل از اینکه بخواید همه mysql_query() هاتونو به این تابع عوض کنید بدونید که این تابع مشکلاتی هم داره و ممکنه به خوبی mysql_query() جواب نده. قبل هرکاری فکر کنید.

منابع
http://www.kiran.org.in/content/mysqlque...feredquery
http://www.mcgelligot.com/2011/12/01/php...red_query/
http://www.tuxradar.com/practicalphp/9/4/9
غایب
  پاسخ
تشکر شده توسط : undefined admin zoghal oia Reza game100
#2
اوه اینو که من خیلی وقت پیش خونده بودم.
هم در منوال PHP و هم در C API خود MySQL.

ضمنا فکر میکنم وقتی mysql_unbuffered_query برای واکشی هر رکورد یک ارتباط با MySQL از طریق سوکت انجام میشه. یجورایی شبیه اینکه به ازای هر رکورد یک کوئری اجرا کنی. البته حتما بارش خیلی کمتر از کوئری های معمولیه، ولی بهرحال یک ارتباط سوکتی هست دیگه. یک رفت و برگشت داره. یک درخواست و پاسخ. و این خودش میتونه یک زمانی رو مصرف بکنه. حالا اینکه چقدر در چه شرایطی و کجا تاثیر داره نمیدونم. اما میتونم حدس بزنم که mysql_query برای بیشتر برنامه ها بهینه تره. mysql_unbuffered_query احتمالا برای شرایط خاصی بهش نیاز میشه.

منکه زیاد خیال این حرفا رو نمیکنم.
همونطور که میبینی برای حساب کردن پرفورمنس و اینکه کجا چی بهینه تره خیلی جزییات و دونستن تمام طرز کار و مشخصات اون دستور و عملیات مورد نیازه. وگرنه ممکنه اشتباه یا حتی برعکس برآورد کنی. یا یه راه دیگه هم میتونه این باشه که بنچمارک کنی. اما بنچمارک هم هر جایی و هرموردی و هر شرایطی نمیشه بسادگی انجام داد.

پس بازم میرسیم به این قاعدهء بهینه سازی که اصولا تا لازم نشده و به مشکلی برخورد نکردید دنبال بهینه سازیهای جزیی نرید.
اون چیزی که بصورت پیشفرض گذاشتن معمولا در بیشتر موارد بهینه ترین هست. همچنین ساده ترین راه در بیشتر برنامه ها بهینه ترین راه هم هست درکل (یا حداقل پرفورمنس خوب/کافی داره).

البته mysql_unbuffered_query هم چون یک تفاوت فاحشی داره در روش کار، حتما بعضی جاها میتونه واقعا مفید و مشکل گشا باشه.

بعد این سوال هم پیش میاد که خود MySQL آیا داده های واکشی شده رو در RAM نگهداری نمیکنه؟ به این شکل در بیشتر سناریوها که MySQL و PHP هر دو روی یک سرور هستن از نظر مصرف مموری نباید تفاوت چندانی باشه. حتی اگر بطور پیشفرض داده ها رو در RAM نگهداری نکنه، ولی درمورد عملیاتی مثل مرتب سازی و بطور کلی کوئری های پیچیده آیا نیازی به این کار نداره؟
  پاسخ
تشکر شده توسط : game100
#3
نقل قول:یا یه راه دیگه هم میتونه این باشه که بنچمارک کنی. اما بنچمارک هم هر جایی و هرموردی و هر شرایطی نمیشه بسادگی انجام داد.
اتفاقا در یکی از همون منابع ذکر شده خوندم که ذاتا تفاوتی در استفاده از این دو تابع نیست. حتی یه مثالی هم زده بود ساده. در این صورت حتی بنچمارک هم چیزی رو نشون نمیده. همینطور mysql_query() تابع استاندارد اجرای کوئری تعریف شده. این بدین معنیه که بیشتر جاها این کاربرد داره تا اون یکی. و دقیقا با صحبت شما موافقم.

این رو هم خوبه بخونید.
نقل قول:Unbuffered result sets on the other hand are kept much longer on the server. If you want to reduce memory consumption on the client, but increase load on the server, use unbuffered results.
نقل قول:مجموعه نتایج بافر نشده مدت بیشتری روی سرور نگهداری میشن. اگر بخوای مصرف مموری رو در سمت کلاینت کاهش بدی اما زمان بارگذاری روی سرور رو افزایش بدی، از نتایج بافر نشده استفاده کن.
http://dev.mysql.com/doc/refman/5.5/en/a...stats.html
غایب
  پاسخ
تشکر شده توسط : vejmad admin game100


پرش به انجمن:


کاربران در حال بازدید این موضوع: 1 مهمان