PDA

View Full Version : تعداد کانکشن های مجاز



masiha68
یک شنبه 18 فروردین 1392, 16:46 عصر
سلام
من سایتم رو که میارم اکثرا با پیغام
Fatal error: Too many connections in... رو به رو می شم
طبق پیغام میگه که تعداد کانکشن ها زیاد از حده ولی نمی دونم مشکل از طراحی سایته یا مشکل از هاسته
سوال دومی اینه که واسه صفحه ی اصلی چندتا کانکت شدن به دیتابیس مجازه وهر کدوم چقد از رم و سی پی یو رو اشغال میکنه
البته اینم بگم من قبلا هاستم رو سر این مسئله عوش کردم و از اون هاستیگ هم پرسیدم و جواب ندادن

pani.khoram
یک شنبه 18 فروردین 1392, 18:54 عصر
سلام
این موضوع تعداد بالای کانکشن به چند مورد بستگی داره :
یک : تعداد باز و بسته کردن کانکشن ها .
دو : استفاده کردن از چه شیوه ارتباط با دیتابیس : PDO , pconnect , ...
سه : تعداد بازدید کنندگان سایت
میزان به انجام رسیدن یک کوری در سیستم شما .

فرض بگیرید شما ، یک کوری خیلی سنگین در صفحه دارید ، و در کنار این 5 تا کوری کوچک دیگه هم اجرا شده ، حالا با فرض اینکه همزمان 20 نفر به سایت شما رجوع کنند و این صفحه رو ببیند ، می بینید که بار فشاری که به سرور شما می اید با اعدادی که حساب کردید متفاوت خواهد بود و این دلیل بر اینه که وقتی چند کوری همزمان سنگین وجود داره توانایی سرور شما برای پاسخگویی بسیار پایین می آید ، ماشین وقتی سرعتش بالای 140 بره هم مصرف بنزینش و هم توان و شتابش بسیار افت می کنه چون نیاز به توانایی بالاتری خواهد داشت .
یک مانیتور ساده رو سیستم خودتون نصب کنید و سایت رو به شکل لوکال هاست مورد بررسی قرار بدید . اگه تمام کوری های شما فرض بگیریم اصولی طراحی شده باشه باید بررسی کنید که نیاز سیستمی شما دقیقا چه قدر خواهد بود که این هم باز توسط همون نرم افزار های مانیتورینگ می تونید مشاهده کنید .
پس برای حمل یک بار سنگین شما هر کاری کنید نمی تونید با یک ماشین سواری ساده جابه جایی رو انجام بدید و نیاز به توان بالاتر یا همون ماشین های قوی تر دارید .
حالا در مرحله آخر اگر واقعا کد شما صحیح و فقط مشکل بار و توانایی شما در پاسخگویی بود می تونید از load balancer یا replication سرور برای نیاز خودتون استفاده کنید .
سوال شما رو نمی شه خیلی ریز پاسخ داد نیاز به بررسی داره و باید حتما زیر بار مانیتور بشه تا راه حل مناسب براشون پیدا بشه ولی در کل 80 درصد زمان خودتون رو بگذارید واسه optimaze کردن کوری هاتون .
با تشکر

MMSHFE
یک شنبه 18 فروردین 1392, 21:51 عصر
بطور کلی بهتره وقتی کارتون با دیتابیس تمام شد، اتصال رو ببندین. اینطوری اگه توی بقیه اسکریپت، کار طولانی مدتی داشتین که نیازی به دیتابیس نداشت و داده های موردنیاز قبلاً استخراج شده بود، دیگه اتصال تا پایان اجرای اسکریپت باز نمیمونه. این مسئله در درخواستهای همزمان به میزان چشمگیری تعداد اتصالهایی رو که همزمان باز شدن، کاهش میده. بعد از این مسئله، به فکر بهینه سازی کوئریهایی که نوشتین باشین و از کوئریهای سریع استفاده کنید.

Veteran
یک شنبه 18 فروردین 1392, 23:03 عصر
به فکر بهینه سازی کوئریهایی که نوشتین باشین و از کوئریهای سریع استفاده کنید.
جناب شهرکی میشه در این مورد اطلاعاتی رو ارائه بدید
مثلا چه کوئری از یک کوئری دیگه سریع تر هست ؟
استفاده از store procedure میتونه به ما توی این زمینه کمک کنه که کوئری هامون سریعتر اجرا بشه ؟

MMSHFE
دوشنبه 19 فروردین 1392, 08:23 صبح
ببینید درمورد کوئریهای بهینه زیاد صحبت شده. مثلاً در اکثر موارد، استفاده از دو کوئری جداگانه سریعتر از Join هست. یا اینکه برای صفحه بندی، ترتیبی اتخاذ کنید که حتی الأمکان از LIMIT بدون Offset استفاده بشه و رکوردها رو تا جایی که ممکنه با WHERE جدا کنید. یا مثلاً اگه اطلاعاتی دارین که زیاد خونده میشه و تغییر توشون بندرت اتفاق میفته، اونها رو Cache کنید (توی فایل یا هرجور دیگه که صلاح میدونید - مثلاً در اولین بازدید توی سشن بریزین). Stored Procedure باعث افزایش سرعت کوئری نمیشه. فقط سرعت اسکریپت رو کمی افزایش میده چون تابع توی خود MySQL تعریف شده و محل اجراش توی خود دیتابیسه و این باعث میشه بتونیم دستوراتمون رو مستقیماً روی رکوردها اجرا کنیم نه اینکه همه رو برگردونیم به PHP و اونجا عمل فیلترکردن و سایر کارهای موردنیاز رو انجام بدیم. درهرحال SP چیزی نیست که بشه بعنوان عامل افزایش سرعت ازش استفاده کنیم. یکی دیگه از فاکتورهای بهینگی کوئری، توی ترتیب شرطهای ترکیبی در WHERE هست. برای مثال دو کوئری زیر رو درنظر بگیرین:

SELECT * FROM `grades` WHERE (`stu_id`='5' AND `score`<'10') ORDER BY `id`
SELECT * FROM `grades` WHERE (`score`<'10' AND `stu_id`='5') ORDER BY `id`

تنها تفاوت دو کوئری فوق، ترتیب شرطهاست. اما اگه تعداد دانشجوها زیاد باشه و درنتیجه رکوردهای جدول grades هم خیلی زیاد بشه، طبیعتاً کوئری اول سریعتر اجرا میشه چون همون ابتدا، تمام رکوردهایی که مربوط به دانشجوی شماره 5 نیست، حذف میشن و شرط دوم روی رکوردهای باقیمانده بررسی میشه اما در کوئری دوم، اول تمام نمرات زیر 10 استخراج میشن و بعد اونهایی که مربوط به دانشجوی شماره 5 نیست، از نتیجه جستجو حذف میشه. البته این شرایط برای وقتی هست که برنامه رو مثلاً برای دانشگاه مینویسید. اگه همین برنامه رو بخواین برای دبیرستان یا آموزشگاه بنویسید، کوئری دوم سریعتر خواهد بود چون معمولاً در دانشگاه تعداد کل نمرات زیر 10 بیشتر از تعداد نمرات یک دانشجو هست اما در دبیرستان و آموزشگاه معمولاً تعداد نمرات زیر 10 خیلی کمه و بهتره اول این نمرات رو پیدا کنیم و بعد ببینیم کدومش مربوط به دانش آموز/هنرجو شماره 5 هست. بنابراین بهتره همیشه ترتیبی رو توی شرطها انتخاب کنید که به ترتیب از اولین شرط که بسمت آخری حرکت میکنیم، بیشترین رکوردها رو از دایره انتخاب خارج کنه.

masiha68
دوشنبه 19 فروردین 1392, 09:44 صبح
خیلی ممنون از جوابتون ... خیلی بهم کمک کرد
در مورد سایت خودم باید بگم که من دوتا سایت روی یهی هاست و یه سایت دیگه روی هاست دگه دارم و اون دوتا سایتم که روی یه هاسته معمولا با هم از کار می افتن و اون سایت دیگه سالمن ... واسه همین فک می کنم مشکل از هساست باشه نه از سایت
در مورد تعداد کوئری ها هم واسه فایل ایندکس که همون ص اصلی حساب میشه و باید تقریبا بیسشتر اطلاعات لود بشه من از هشت تا کوئری از دیتابیس میگیرم
1 - اصلاعات سایت 2 تعداد نظرات 3 پست ها 4 اخرین ارسال های پست ها 5 لینک دوستان 6 امارگیر و اطلاعات قسمت اپلود و اخرینش یادم نیست
نمیشه هیچکدوم از این ها رو حذف کرد چون به همشون نیاز دارم
یه سوا دیگه که دارم اینه که چه وقتی یه کانکشن رو ببندم وقتی کل ص لود شد یا وقتی اطلاعات کئوری رو توی یه متغییر ذخیره کردیم
ممنون

MMSHFE
دوشنبه 19 فروردین 1392, 10:13 صبح
ببینید تعداد کوئریها اصلاً مهم نیست. این تعداد و بهینگی اونها فقط سرعت استخراج اطلاعات رو مشخص میکنه. شما وقتی که اطلاعات رو از دیتابیس خوندین و توی متغیر گذاشتین و دیگه توی اسکریپت به دیتابیس نیاز نداشتین، بهتره اتصال رو ببندین. حالا اینکه چقدر کوئریهای شما بهینه نوشته شده باشه مشخص کننده مدت زمانی هست که از لحظه بازشدن اتصال تا بسته شدنش (یعنی زمان اجرای کوئری) اتصال باز هست. برای مثال، فرض کنید یک اسکریپت دارین که 5 ثانیه اجراش طول میکشه و 4 ثانیه از این زمان بخاطر یک حلقه تودرتو و پیچیده است که روی اطلاعات کار میکنه اما اطلاعات رو قبل از حلقه از دیتابیس استخراج و توی متغیر گذاشتین. خوب اگه قبل از حلقه، اتصال رو ببندین، فقط 1 ثانیه اتصال باز بوده و در 4 ثانیه بعدی که اسکریپت داره اجرا میشه، یک کلاینت دیگه میتونه بیاد و دوباره یک اتصال برقرار کنه درحالی که اگه بگذارین اتصال باز باشه، کل 5 ثانیه اتصال رو در اختیار دارین و وقتی اسکریپت کارش تمام شد و خروجی رو میخواد به مرورگر کلاینت بفرسته، اتصال بسته میشه. درنتیجه اگه مثلاً سایت شما 200 بازدیدکننده همزمان داشته باشه، به مدت 5 ثانیه 200 اتصال باز دارین و بسته به تنظیمات هاست، ممکنه درخواستهای جدید با پیغام خطا مواجه بشن. من خودم توی پروژه هام، از کلاسی که نوشتم استفاده میکنم. این کلاس برای اجرای کوئری، یک اتصال باز میکنه، کوئری رو اجرا میکنه، نتیجه رو توی یک آرایه دوبعدی PHP میریزه، اتصال رو میبنده و آرایه رو return میکنه. البته یکسری امکانات دیگه هم داره (مثل Escapeکردن و...) که موضوع بحث نیست.
-----
پاورقی: دکمه تشکر کاربرد مناسبتری داره. موفق باشید.

masiha68
دوشنبه 19 فروردین 1392, 12:53 عصر
من تقریبا تموم کتاب هایی رو که دادین بیرون و فیلم های اموزشی شما رو نگاه کردم و خوندم و تقریبا از کلاس های شما استفاده می کنم ( البته با یه سری تغییرات) مثلا واسه سایت پوول یا همون نظر سنجی یه کلاس واسه کانکنت شدن به دیتابیس ایجاد کردید و توی تابع ها از اون استفاده می کنین حالا سوال اینه وقتی تابع بسته شد و نتیجه ریترن شد کانکشن هم بسته میشه ؟؟

پی نوشت :
این تایپیک خیلی چالب شد و خیلی چیزای یاد گرفتم :)
گاهی دکمه ی تشکر کفایت نمی کنه

MMSHFE
دوشنبه 19 فروردین 1392, 13:41 عصر
توی اون کلاسی که توی فیلم گذاشتم، نه بسته نمیشه و باید خودتون با فراخوانی تابع disconnect که اینطوری مینویسید، بعد از استفاده از خروجی تابع query اتصال رو ببندید:


function disconnect() {
connect(); // To ensure there is an active connection to close
mysql_close();
}

البته باید دقت کنید که از اونجا که خروجی تابع query یک Resource از MySQL هست، تا وقتی که اطلاعات رو ازش fetch نکردین، نباید اتصال رو ببندین. برای راحتی بیشتر، میتونید از این تابع استفاده کنید:


function a_query($query) {
connect();
$info = query($query);
$result = array();
if($info && mysql_num_rows($info) > 0) {
while($row = mysql_fetch_assoc($info)) {
$result[] = $row;
}
}
disconnect();
return $result;
}

این تابع، همونطور که میبینید، اول به دیتابیس وصل میشه، بعد کوئری رو به تابع query میده (که توی فیلم آموزشی قبلاً نوشتیمش)، بعد سطر به سطر اطلاعات رو استخراج میکنه و میریزه توی آرایه result$ و بعد اتصال رو میبنده و نهایتاً آرایه result$ رو برمیگردونه. مزیت این تابع اینه که خروجی الآن یک آرایه معمولی PHP هست که هر سطرش یک رکورده و خونه های سطرها هم با اسامی فیلدها قابل استخراج هستن. مثلاً فیلد name سطر چهارم رو میشه با ['result[3]['name$ بدست آورد.

masiha68
دوشنبه 19 فروردین 1392, 17:59 عصر
تا اینجا که فوق العاده بود ... فقط یه سوال می مونه
یه کانکشن تا کی باز می مونه یعنی اگه یه کانکشن رو خودمون نبندیم تا کی باز می مونه
کد زیر رو نگاه کنین :

<?php
include_once('config.php');
connect();


$sql=query("select * from post where type='web' order by id desc limit 10");
echo "<h2>آخرین طرح های وب</h2>";
while($row=mysql_fetch_assoc($sql))
{

if($row['type']=="web" && $row['vaziat']=="1")
{
echo "<a href='web.php?id=" .$row['id']."&type=web'>" .$row['title']. "</a>";

}

}
//// last blog

$sql1=query("select * from post where type='blog' order by id desc limit 10");
echo "<h2>آخرین نوشته های وبلاگ</h2>";
while($row1=mysql_fetch_assoc($sql1))
{

if($row1['type']=="blog" && $row1['vaziat']=="1")
{
echo "<a href='blog.php?id=" .$row1['id']."&type=blog'>" .$row1['title']. "</a>";

}

}

//last book
$sql=query("select * from post where type='book' order by id desc limit 10");
echo "<h2>آخرین کتاب ها</h2>";
while($row=mysql_fetch_assoc($sql))
{

if($row['type']=="book" && $row['vaziat']=="1")
{
echo "<a href='book.php?id=" .$row['id']."&type=book'>" .$row['title']. "</a>";

}

}
//last pic
$sql=query("select * from post where type='pic' order by id desc limit 10");
echo "<h2>آخرین عکس ها</h2>";
while($row=mysql_fetch_assoc($sql))
{

if($row['type']=="pic" && $row['vaziat']=="1")
{
?> <a href="pic.php?id=<?php echo $row['id'];?>&type=pic"><img src="<?php echo $row['pic'] ;?>" height="50" width="50" title="<?php echo $row['title'];?>"/></a>




<?php
}

}
echo "<h2>آخرین دیدگاه های تایید شده</h2>";
include('lastcomment.php');
// my frend :) //

$sql=query("select * from link order by id desc ");
echo "<h2>دوستان و آشنایان</h2>";
while($row=mysql_fetch_assoc($sql)){
?>
<a target="_new" href="http://<?php echo $row['url'];?>" title="<?php echo $row['title'];?>"><?php echo $row['name'];?></a>

<?php
}

?>

توی این کد من واسه هر بار حلقه ی ویل مجبور شدم یه کوئری از دیتابیس بگیرم ( می خواستم واسه ی همه ی حلقه ی های ویل از یک کوئری استفاده کنم خطا میداد) یعنی اونجوری که من استنباط کردم بعد از اینکه mysql_fetch_assoc() تموم میشه کانکشن هم خودش بسته میشه

MMSHFE
دوشنبه 19 فروردین 1392, 18:10 عصر
کانکشن بطور پیشفرض با اتمام تفسیر اسکریپت توسط مفسر PHP و قبل از ارسال خروجی به مرورگر کلاینت، بسته میشه. مگه اینکه با mysql_pconnect اتصال از نوع Persistent ایجاد کرده باشین.