PDA

View Full Version : error mySql



tehro0n
شنبه 15 مهر 1391, 14:14 عصر
برای رفع این اررور نیاز به RAM بیشتر دارم یا CPU ؟

Warning: mysqli::mysqli() [mysqli.mysqli]: (08004/1040): Too many connections in /config.php on line 10
Connect failed: Too many connections

Unique
شنبه 15 مهر 1391, 21:08 عصر
مگه شما چند تا connection ایجاد میکنید ؟
هر connection را پس از اتمام کار میبندید ؟

tehro0n
شنبه 15 مهر 1391, 22:51 عصر
بله پس از اتمام می بندم
ولی خوب فکر می کنم حدود 1.5 میلیون کانکشین در دوماه باشه..
چون انقدر رکورد رو در ابزارهام دارم..
تو فکر کش کردن کوئری هام ولی مطلب درستی پیدا نمی کنم!

Hamid.RDN
دوشنبه 17 مهر 1391, 01:26 صبح
جواب : نه RAM نه CPU

دوست عزیز سرور ، بانک اطلاعاتی ، کانکشن ها و برنامه تون رو اصلاح کنید.

shahriyar3
دوشنبه 17 مهر 1391, 14:17 عصر
فکر میکنم در نسخه های جدید تر دیگه لازم نیست بعد از هر ارتباط کانکشن ها رو ببندید
بستن کانکشن ها بار اضافه روی سرور ایجاد میکنه

exlord
دوشنبه 17 مهر 1391, 18:53 عصر
این اررور ربطی به cpu یا ram نداره ...
اول اسکریپتتون رو چک کنین که آیا برای هر اسکریپت یک کانکشن ایجاد میشه یا برای هر query ... ?
php خودش بعد از پایان اجراش تمام کانکشن هایی رو که باز کرده میبنده پس نیازی به بستنشون نیست ...
اگه اسکریپتتون درست نوشته شده یعنی به ازای هر اسکریپت فقط یک کانکشن ایجاد میشه ... در این صورت اگه سرورتون VPS یا dedicate هست محدودیت تعداد کانکشن هارو در تنظیمات mysql بیشتر کنین .... در غیر این صورت برنامتون رو محدود به تعداد کاربر خاصی بکنین که تعدادشون از حد نصاب بیشتر نشه ...

tehro0n
چهارشنبه 19 مهر 1391, 12:39 عصر
من نسخه جدید آپاچی رو دارم استفاده میکنم، و phpMyAdmin جدید روش نصبه، کانکشن رو محض احتیاط می بدنم، نمونه استفاده از کانکشن هم به این صورته
در فایل کانفیگ

define("HOST", "localhost");
define("USER", "root");
define("PASS", "");
define("DB", "test");
در فایل اصلی

include_once("config.php");
function str_escape($mysqli, $str) {
if (get_magic_quotes_gpc())
$str = stripslashes($str);
return $mysqli->real_escape_string($str);
}
$mysqli = new mysqli(HOST, USER, PASS, DB);
// check connection
if ($mysqli->connect_errno) {
printf("Connect failed: %s\n", $mysqli->connect_error);
exit();
} else
$mysqli->set_charset("utf8"); // change character set to utf8
$ip = $_SERVER['REMOTE_ADDR']; // for example '176.227.203.241'; us
$result = $mysqli->query (
"SELECT
`v`.* , `i`.`country`
FROM
`sites` `s`,
`visits` `v`,
`ip2nation` `i`
WHERE
`s`.`url` = '{$url}'
AND
`s`.`id` = `v`.`id`
AND
`i`.`ip` < INET_ATON('{$ip}')
ORDER BY
`i`.`ip` DESC
LIMIT 0,1");

if ($result->num_rows == 1) { // we have this site
...
$res = $result->fetch_assoc();
// close result set
$result->free();
...
// close connection
$mysqli->close();
که این کوئری بدترین کوئری است که اجرا میشه به دلیل 3 table بودن و گرفتن ip و چک کردن کشور مربوط به ip
کلا این فایل حدود 1.5 میلیون بار در دو ماه اجرا شده، از سرور VPS استفاده می کنم و RAM دو گیگ گذاشتم که همین جور داره رم بیشتر میشه و پایین نمیاد!
چه کنیم؟

exlord
چهارشنبه 19 مهر 1391, 18:53 عصر
با پشتیبانی سرورت تماس بگیر تا تنظیماتشو چک کنن و در صورت نیاز max_connection رو برای mysql بیشتر کنن ...

tehro0n
پنج شنبه 20 مهر 1391, 00:35 صبح
ماکزیمم کانکشن چقدره حالت عادیش و من چقدر باید بکنم؟
اگه بفرمایید از کجا هم ممنون میشم چون من تنها VPS گرفتم و پشتیبانی نداره
حالا چرا اینهمه باید RAM بگیره؟
اگه کوئری ها رو کش کنم بهتر میشه!

exlord
پنج شنبه 20 مهر 1391, 06:16 صبح
ماکزیمم کانکشن چقدره حالت عادیش و من چقدر باید بکنم؟
اگه بفرمایید از کجا هم ممنون میشم چون من تنها VPS گرفتم و پشتیبانی نداره
حالا چرا اینهمه باید RAM بگیره؟
اگه کوئری ها رو کش کنم بهتر میشه!
ربطی به RAM نداره ... توی phpmyadmin قسمت variables ببین max connection چقدره ؟

exlord
پنج شنبه 20 مهر 1391, 08:57 صبح
البته 1.5 میلون کوئری در 2 ماه چیز زیادی نیست و سرور با همون تنظیمات پیش فرضشم نباید کم بیاره ... این کوئری که شما نوشتین (full join) به نظر من مشکل داره و سربار رو سیستم ایجاد میکنه ... شما بهتره اینارو left join بکنین ...

tehro0n
پنج شنبه 20 مهر 1391, 12:08 عصر
من مدل join رو نمی دونم دقیقا چطوری نوشته میشه، نمونه کوئری که دادم همیشه به همین صورت می نویسم.. از php.net نوشتن روش کوئری ها رو یاد گرفتم که مدل join استفاده نمی کرد، البته شنیدم در مورد این مدل نوشتن ها..
باید چند مثال پیدا کنم و درکش کنم..
max connection هم اینجا 151 هست، خوبه یا زیاد کنم؟

tehro0n
پنج شنبه 20 مهر 1391, 12:19 عصر
left join رو از w3schools.com یاد گرفتم..
کاربرد left برای زمانی هست که بیش از یک table داریم؟ یا کلا استفاده می کنید

exlord
پنج شنبه 20 مهر 1391, 15:27 عصر
شما ساختار اون 3 تا جدولتو بگو + این که دقیقا چه خروجی میخوای تا کوئریشو برات بنویسم ...

tehro0n
جمعه 21 مهر 1391, 13:32 عصر
این جدول برای آمارگیر سایت است
ساختار جدول sites
id, url و ستون های دیگه که در اینجا لازم نیست
ساختار جدول visits
بازدیدهای 30 روز گذشته و بازدیدکنندگان 30 روز گذشته و بازدید و بازدیدکننده 12 ماه گذشته و .. که حدود 80 ستون شده است ( پرس و جو و تحقیق کردم دیگران فرمودند اگه برای افزایش بازدید تعداد بازدید رو بگیرم و یکی اضافه کنم و آپدیت، با این که 80 ستون میشه اما بهتر از اینه که برای هر بازدید یک insert بگذارم و برای نمایش خروجی COUNT کنم
ساختار جدول ip2nation
جدولی با دو ستون ip و مخفف کشورهای مربوط به همان آی پی
در این جدول 38000 ردیفی برای هر بازدید میاد چک می کنه که ببینه آی پی مربوطه به کدام کشور است و مخفف آن را در جدولی دیگر ثبت می کند

خروجی جدول
چون چند جدول وجود داره یک id انحصاری برای هر url در نظر گرفتم +
80 ستون جدول visits برای آپدیت جدید


SELECT
`v`.* , `i`.`country`
FROM
`sites` `s`,
`visits` `v`,
`ip2nation` `i`
WHERE
`s`.`url` = '{$_url}'
AND
`s`.`id` = `v`.`id`
AND
`i`.`ip` < INET_ATON('{$_ip}')
ORDER BY
`i`.`ip` DESC
LIMIT 0,1


Showing rows 0 - 0 ( 1 total, Query took 0.1117 sec)

max connection هم اینجا 151 هست، خوبه یا زیاد کنم؟

tehro0n
جمعه 21 مهر 1391, 13:46 عصر
یک مورد دیگه هم هست در ابزار نظر سنجی که باعث شده از دو کوئری استفاده کنم و می خوام یک کوئری بشه
ساختار دو جدول url و item
در url
در اینجا نیز id و url و سئوال و موضوع و زمان تمام شدن نظرسنجی است
در item
عنوان های پاسخ ها و رای های داده شده

حالا ما می خواهیم در صورتی که زمان نظر سنجی تمام نشده است این ابزار را که شامل سئوال و موضوع و (عنوان های پاسخ نظرسنجی که ممکن است 2 ردیف و یا n ردیف باشد) را نمایش دهیم
این روشی است که من استفاده می کنم که جستجو کردم با همین left join و group contact نمونه ای دیدم که هنوز روش کار نکردم


$result = $mysqli->query(
"SELECT
`question`,`title`,`end_time`
FROM
`url`
WHERE
`id` = {$_id}");
$res = $result->fetch_assoc();
// close result set
$result->free();
if ($REQUEST_TIME < $res['end_time']) { // we have this poll
$result = $mysqli->query(
"SELECT
`title`
FROM
`item`
WHERE
`id` = {$_id}
ORDER BY `item`");


در این حالتی که من نوشته بودم چون جدول url تک ردیف است و جدول item چند ردیف می شود کوئری را نمی شد با دو سلکت در یک کوئری گرفت

exlord
جمعه 21 مهر 1391, 18:20 عصر
بازدیدهای 30 روز گذشته و بازدیدکنندگان 30 روز گذشته و بازدید و بازدیدکننده 12 ماه گذشته و .. که حدود 80 ستون شده است ( پرس و جو و تحقیق کردم دیگران فرمودند اگه برای افزایش بازدید تعداد بازدید رو بگیرم و یکی اضافه کنم و آپدیت، با این که 80 ستون میشه اما بهتر از اینه که برای هر بازدید یک insert بگذارم و برای نمایش خروجی COUNT کنم
من سواد چندانی ندارم ولی به نظر من روشتون کاملا اشتباهه 1 insert/update به اضای هر بازدید روی 3 ستون (date - ip - count) خیلی سریعتر از update روی 80 تا ستونه ...

tehro0n
جمعه 21 مهر 1391, 22:48 عصر
این روش شما نیز صحیح است اما موقعیت ثبت بازدیدها و ستونهای دیگری که موجود است و .. باعث شده در آخر چنین کاری را انجام دهم، چون با روش شما نیز هر url باز چند ردیف خواهد شد و باید COUNT گرفت که اطلاعات کنارش تنها یک ردیفه است و باید یک جدول جدا ایجاد شود و اینکه اگه بازدید 2 سال قبل را بخواهیم باید COUNT کل دوسال آخر را بگیریم که خیلی بد است!
حالا شما فرمودید روش بهینه سازی دو کوئری بالا را می توانید انجام دهید چرا چیزی ننوشتید؟
اگه خروجی بهتری دارید با همین دیتا بیس بفرمایید ممنون میشم

exlord
شنبه 22 مهر 1391, 05:57 صبح
اگه بازدید 2 سال قبل را بخواهیم باید COUNT کل دوسال آخر را بگیریم که خیلی بد است!
بد نیست روش درستش همینه ...
شما با مفاهیم database normalization چقدر آشنایی دارین ؟ دیتابیش شما اصلا normalize نشده .... و ساختارش کاملا اشتباهه ...

چون با روش شما نیز هر url باز چند ردیف خواهد شد و باید COUNT گرفت که اطلاعات کنارش تنها یک ردیفه است و باید یک جدول جدا ایجاد شود
درستشم همینه که یه جدول جداگانه ساخته بشه (normalization) ...

exlord
شنبه 22 مهر 1391, 05:57 صبح
حالا شما فرمودید روش بهینه سازی دو کوئری بالا را می توانید انجام دهید چرا چیزی ننوشتید؟
چیزی رو که اشتباهه نمیشه بهینه کرد ...

tehro0n
شنبه 22 مهر 1391, 13:16 عصر
پس اگه میشه یه نمونه کوچک از ساختار این نوع دیتابیس را ضمیمه کنید شاید چیزی که می گید رو من متوجه نمیشم و چیز دیگه ای رو فکر میکنم و بهتره ببینم
اگه مثال را زدید کوئری چند ردیفه و یک ردیفه هم در آن باشه..

در مورد کوئری دومی که نوشتم چی؟ اون بحثش فرق می کنه و در مورد همین چند ردیفه و تک ردیفه از دو جدوله
http://barnamenevis.org/showthread.php?363850-error-mySql&p=1609394&viewfull=1#post1609394

exlord
شنبه 22 مهر 1391, 15:45 عصر
کوئری دومی درسته باید از 2 تا کوئری استفاده بکنب ...

CREATE TABLE `counter` (
`visit_date` int(10) NOT NULL,
`url_id` int(11) NOT NULL,
`nation_id` int(11) NOT NULL,
`visit_count` int(11) DEFAULT NULL,
PRIMARY KEY (`visit_date`,`url_id`,`nation_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


$q2 = "INSERT INTO
`counter`
(
`visit_date`,
url_id,
nation_id,
`visit_count`
)
VALUE (
%s,
(select id from sites where url='%s'),
(select id from nation where ip='%s'),
%s
)
ON DUPLICATE KEY UPDATE visit_count=visit_count+1;";


BaseDAL::GetInstance()->ExecuteNoneQuery($q2, array(date('Ymd'), $url, $ip, 1));


public static function GetVisitCount($date = false)
{
$where = '';
if ($date)
$where = 'where visit_date=' . $date;
$q = "select sum(visit_count) from counter $where";
$num = BaseDAL::GetInstance()->GetScalar($q);
if (empty($num))
$num = 0;
return $num;
}


public static function GetTodayVisitCount()
{
return self::GetVisitCount(date('Ymd'));
}

public static function GetYesterdayVisitCount()
{
return self::GetVisitCount(date("Ymd", strtotime("-1 day")));
}

tehro0n
یک شنبه 23 مهر 1391, 15:16 عصر
خوب من انتظار داشتم که شما برای کوئری دوم با این اطلاعاتی که دارید پاسخ زیر را بدهید..


SELECT
`u`.`question`,`u`.`title`,
GROUP_CONCAT(`i`.`title` ORDER BY `i`.`item` ASC SEPARATOR ',') AS `items`
FROM
`url` `u`
LEFT JOIN `item` `i`
ON `i`.`id` = `u`.`id`
WHERE
`u`.`id` = {$_id}
AND
(`u`.`end_time` = 0 OR `u`.`end_time` > {$REQUEST_TIME})

این روش خیلی بهتر از اینه که شما یک if در کدنویسی php بگذارید و مهمتر از همه دو کوئری برای خروجی داشته باشید

اینجور مسائل برای من خیلی اهمیت داره چون با یک کاربر و چند کوئری سر و کار ندارم،
در مورد ساختار دیتابیس آمارگیر شما هم باز برای چند یوزر خوبه، وقتی کاربر عادی 10000 بازدید در سال داشته باشه و شما حداقل 50000 کاربر داشته باشید، در یک بازه زمانی برای نمایش آمارگیر سال گذشته (به غیر آمارهای روزانه دیگر) تقریبا در هر ثانیه باید 100 میلیون ردیف شمارش بشه که اصلا خوب نیست!
در phpMyAdmin شما می تونید تا 1000 ستون هم داشته باشید که به حجم اطلاعات هر ستون بستگی داره، بنابراین اگر شما از روش ستون استفاده کنید به جای 100 میلیون رکورد 4 ستونی می تونید 10000 رکورد 80 ستونی داشته باشید
در این محاسبات فرض بر این گرفتیم که 10000 کاربر در همان لحظه آن لاین بودند

exlord
یک شنبه 23 مهر 1391, 15:56 عصر
در یک بازه زمانی برای نمایش آمارگیر سال گذشته (به غیر آمارهای روزانه دیگر) تقریبا در هر ثانیه باید 100 میلیون ردیف شمارش بشه که اصلا خوب نیست!در یک بازه زمانی برای نمایش آمارگیر سال گذشته (به غیر آمارهای روزانه دیگر) تقریبا در هر ثانیه باید 100 میلیون ردیف شمارش بشه که اصلا خوب نیست!
در مورد کش کردن تحقیق کنید.

در phpMyAdmin شما می تونید تا 1000 ستون هم داشته باشید که به حجم اطلاعات هر ستون بستگی داره، بنابراین اگر شما از روش ستون استفاده کنید به جای 100 میلیون رکورد 4 ستونی می تونید 10000 رکورد 80 ستونی داشته باشید
در این محاسبات فرض بر این گرفتیم که 10000 کاربر در همان لحظه آن لاین بودند
در مورد مباحث database normalizations مطالعه کنید .
https://www.google.com/search?q=database+normalizations