PDA

View Full Version : سوال: مشکل فشار به سرور



pirmard66
چهارشنبه 27 شهریور 1392, 16:36 عصر
سلام و عرض ادب خدمت دوستان عزیز

یک تیک کد من مثل اینکه بیش از حد به سرور فشار میاره:

این کد اروری هست که شرکت هاست برام فرستاده :



کوئری دارای مشکل و مشخصات زمان مصرفی آن به صورت زیر است

# Scores: Apdex = 1.00 [1.0], V/M = 0.14
# Query_time sparkline: |^_^_.- |
# Time range: 2013-09-18 09:40:38 to 09:47:28
# Attribute pct total min max avg 95% stddev median
# ============ === ======= ======= ======= ======= ======= ======= =======
# Count 0 3035
# Exec time 13 127s 4us 396ms 42ms 230ms 77ms 144us
# Lock time 0 140ms 0 34ms 46us 47us 805us 0
# Rows sent 0 1.01k 0 1 0.34 0.99 0.47 0
# Rows examine 38 183.68M 0 181.76k 61.97k 174.27k 82.61k 0
# Query size 0 142.27k 48 48 48 48 0 48
# String:
# Databases News
# Hosts localhost
# Users uNews
# Query_time distribution
# 1us ################################################## ##############
# 10us ############
# 100us ##################################################
# 1ms #
# 10ms #############################
# 100ms ###################################
# 1s
# 10s+
# Tables
# SHOW TABLE STATUS FROM `News` LIKE 'visit'\G
# SHOW CREATE TABLE `News`.`visit`\G
# EXPLAIN /!50100 PARTITIONS/
SELECT SUM(n_visit) from visit where p_id='4219'\G

ظاهرا مشکل مربوط به پلاگین آمار و جدول
visit
است.


کدی که نوشتم :



function show($cod)
{
$con=mysql_connect("localhost" ,"*****" ,"888888");
$sdb=mysql_select_db("****",$con);
mysql_query('SET NAMES \'utf8\'');
mysql_set_charset('utf8');
$cod=mysql_real_escape_string($cod);

$result=mysql_query("SELECT SUM(n_visit) from visit where p_id='".$cod."'");
return $result;
}


ممنون میشم دوستان کمکی بکنن ببینیم چرا این تیکه کد فشار میاره !

البته بگم که وقتی بازدیدها زیاد میشن این اتفاق میفته یعنی جدول visit وقتی سنگین میشه اینطوری میشه!

منتظرم
ممنون

rezaonline.net
چهارشنبه 27 شهریور 1392, 17:16 عصر
کوئری سنگین هست چون دارید از تابع sum هم استفاده میکنید .
جدول visit هم حدس میزنم تعداد رکوردهاش بیشتر از 4 رقمی باشه واسه همینه .
بهتره کش کنید اطلاعات رو چون ظاهرا تعداد نمایشهای را برمیگردونید پس زیاد اطلاعات حساسی نیست .

pirmard66
چهارشنبه 27 شهریور 1392, 17:32 عصر
دادا منظورت اینه صفرش کنم؟

یعنی هر دفعه همینکارو بکنم؟

راهی نداره؟

plague
چهارشنبه 27 شهریور 1392, 17:52 عصر
اگه دیتابیست سنگینه بجای اینکه به صورت زنده جمع کنی نتایج رو در هر بار , یه تیبل بزار که نتیجه جمع رو توی خودش زخیره داشته باشه و در هر بار بازدید مقدارش رو یدونه زیاد کن بجای اینکه یه سطر اضافه کنی مثل روش فعلی

rezaonline.net
چهارشنبه 27 شهریور 1392, 19:01 عصر
دادا منظورت اینه صفرش کنم؟

یعنی هر دفعه همینکارو بکنم؟

راهی نداره؟
به جای اینکه با هر درخواست ، این دستور اجرا بشه کشش کن که هر 120 ثانیه(دو دقیقه) یک بار اجرا بشه مثلا .
کلاس کش برات مینویسم .
اینو اضافه کن به اسکریپتت

<?php

/*
* cache class ~ put in file
*
* @author : reza <info@rezaonline.net>
* @pakage : rezaworkshop.ir
* @varsion : 1.0
* @date : 1392/6/27
*/

class cache
{
static private $ins=null;

static private $perfix = '';
static private $cacheDir = null;


static public function ins()
{
if(self::$cacheDir===null)
self::$cacheDir = dirname(__FILE__).'/cache/';

if( ! file_exists(self::$cacheDir))
{
@mkdir(self::$cacheDir, 0777);
$fp = fopen(self::$cacheDir.'index.html', "wb");
if (!$fp)
die('eroor in make cache dir file in file ~ `'. __FILE__ .'` and line `'.__LINE__ .'`');
fwrite($fp, 'cache its work :) <br> www.rezaonline.net');
fclose($fp);
}

if(self::$ins===null)
self::$ins = new self;
return self::$ins;
}

public function setPerfix($str = '')
{
self::$perfix = strip_tags($str);
}

public function hash($str='')
{
return self::$perfix.md5($str);
}


public function add($key=1,$val=1 ,$expire=3600)
{
self::delete($key);
$data = array(
'key'=>$key ,
'val'=>$val ,
'expire'=>time() + $expire ,
);

$fileName = self::hash($key).'.php';
$fp = fopen(self::$cacheDir.$fileName, "wb");
if (!$fp)
die('eroor in make cache dir file in file ~ `'. __FILE__ .'` and line `'.__LINE__ .'`');
fwrite($fp, '<?php die; ?>'.serialize($data));
fclose($fp);

return file_exists(self::$cacheDir.$fileName);
}

public function get($key=1)
{
$fileName = self::hash($key).'.php';
$f = self::$cacheDir.$fileName;
if( ! file_exists($f))
return null;

$data = file_get_contents($f);
if(empty($data))
return NULL;

$data = str_replace('<?php die; ?>','',$data);
$data = unserialize($data);

if(empty($data['expire']) or $data['expire']<time())
{
self::delete($key);
return NULL;
}

if(empty($data['key']) or $data['key']!=$key)
{
self::delete($key);
return NULL;
}

return $data['val'];

}

public function delete($key=1)
{
$fileName = self::hash($key).'.php';
if( ! file_exists(self::$cacheDir.$fileName))
return true;

@unlink(self::$cacheDir.$fileName);
if(file_exists(self::$cacheDir.$fileName))
return false;
return true;
}

public function flush()
{
$path = self::$cacheDir;

if(($handle=opendir($path))===false)
return;
while(($file=readdir($handle))!==false)
{
if($file[0]==='.')
continue;
$fullPath=$path.DIRECTORY_SEPARATOR.$file;
@unlink($fullPath);
}
closedir($handle);

}


}
حالا کدت رو اینطوری بنویس .

function show($cod)
{
$qr = "SELECT SUM(n_visit) from visit where p_id='".$cod."'";

$_ = cache::ins()->get($qr);
if( ! empty($_))
return $_;


$con=mysql_connect("localhost" ,"*****" ,"888888");
$sdb=mysql_select_db("****",$con);
mysql_query('SET NAMES \'utf8\'');
mysql_set_charset('utf8');
$cod=mysql_real_escape_string($cod);

$result=mysql_query($qr);
cache::ins()->add($qr,$result, 120);
return $result;
}

pirmard66
چهارشنبه 27 شهریور 1392, 21:17 عصر
دادا میشه راجع به کارکرد کلاسی که نوشتی توضیح بدی؟

ممنونم از اینکه وقتتو گذاشتی

rezaonline.net
چهارشنبه 27 شهریور 1392, 21:29 عصر
کلاس کش هست .
یه سری مقادیر رو میخوای به جای اینکه پردازش کنی توش ذخیره میکنی و استفاده میکنی تا وقتی که اعتبارش تموم میشه و دوباره آپدیت میکنی .
به طور مثال شما یک سایت خبری داری ، خب لیست تمام خبرهات که همیشه لزومی نداره بزنی select * from news ، یه بار میزنی ، کش میکنی بعدش از کش اطلاعات رو میخونی ، دیگه فشار به سرور نمیاد .

rezaonline.net
چهارشنبه 27 شهریور 1392, 21:32 عصر
اطلاعات کش رو توی فایل مینویسه .
شما از 4 متد add , get , delete و flush استفاده کن
به ترتیب add با سه آرگومان ، اولی کلید کش هست ، دومی مقدارش و سومی میزان نگه داری کش به ثانیه
get کلید رو بهش میدی مقدار رو بهت میده
delete کلید رو بهش میدی و کش رو حذف میکنه
flush تمامی کش ها رو حذف میکنه .

trasilver
سه شنبه 19 آذر 1392, 02:57 صبح
هیچی مشکل حل شد. ممنون بابت فایل خوبتون.

soroush.r70
سه شنبه 19 آذر 1392, 10:31 صبح
دوست عزیز من از pdo برای اتصال به دیتابیسم استفاده می کنم آیا می شه از کلاس کش شما استفاده کرد جایی باید تبدیل بشه به pdo

یه نمونه از فاکشن فراخوانی من :


function slider()
{
$class=new content;
$class->query('select * from `tbl_slider` order by `id` desc');
$row=$class->resultset();
foreach($row as $key => $value)
{
global $count;
$count ++;
echo'
<a><img src="'.upload.''.$row[$key]['pic'].'" alt="'.$row[$key]['title'].'" title="'.$row[$key]['title'].'" id="wows'.$count.'"/></a>
';
}
}

rezaonline.net
سه شنبه 19 آذر 1392, 11:44 صبح
کلاس کش هست دیگه .
میشه استفاده کرد

soroush.r70
پنج شنبه 21 آذر 1392, 12:49 عصر
من تابع خودمو به این صورت تغییر دادم مشکلی نداره



function slider()
{
$class=new content;
$qr=$class->query('select * from `tbl_slider` where `group`=:group order by `id` desc ');
$class->bind(':group','فارسی');
$_ = cache::ins()->get($qr);
if( ! empty($_))
return $_;
$row=$class->resultset();
foreach($row as $key => $value)
{
echo'
<li style="slidedelay: 5000; transition2d: 92,93,105;" > <img src="'.upload.''.$row[$key]['pic'].'" alt="'.$row[$key]['title'].'" />
<div class="wrapper">
<div class="caption lfb huge" data-x="center" data-y="100" data-speed="900" data-start="100" data-easing="easeOutSine">'.$row[$key]['title'].'</div>
<div class="caption lft p-text-slider-2" data-x="center" data-y="200" data-speed="900" data-start="900" data-easing="easeOutSine">'.$row[$key]['text'].'</div>
</div>
</li>
';
}
cache::ins()->add($qr, 120);
return $qr;
}




و یه سوال این کلاس شما زمانی جدول ها به روز بشه مشکلی ایجاد نمی کنه یعنی همون اطلاعات قبلی رو از روی اطلاعات کش شده که فراخوانی نمی کنه....؟

rezaonline.net
پنج شنبه 21 آذر 1392, 15:24 عصر
و یه سوال این کلاس شما زمانی جدول ها به روز بشه مشکلی ایجاد نمی کنه یعنی همون اطلاعات قبلی رو از روی اطلاعات کش شده که فراخوانی نمی کنه....؟
سلام
باید کش رو پاک کنید ، خودش که قدرت تشخیص نداره :)

soroush.r70
شنبه 23 آذر 1392, 14:21 عصر
یعنی با استفاده از کلاس شما به چه صورت می شه انجام داد

rezaonline.net
شنبه 23 آذر 1392, 15:34 عصر
یک مثال :

function getAll()
{
$cache = cache::ins();

$qr = "select * from tbl";
$key = md5($qr);

//return cache if exists
$_ = $cache->get($key);
if( ! empty($_))
return $_;


$result = $this->db->query($qr)->result();

$cache->add($key,$result,3600); //add cache

return $resutl;
}


function update($data='')
{
$cache = cache::ins();
$cache->flush(); //delete all cache

$this->db->query("update ....")->execute();
}

در کل در هنگام آپدیت یا حذف یک رکورد از دیتابیس کل کش ها رو با استفاده از متد flush پاک کنید تا کش های جدید جایگزین بشن .
با استفاده از متد delete میتونید کلید یک کش رو بدید تا فقط همونو حذف کنه .

ساده است یه خورده روش تمرکز کنید متوجه میشید.

us1234
شنبه 23 آذر 1392, 16:27 عصر
سلام
آقا رضا یک سوال ؟
چرا شما برای کلاستون سازنده تعریف نکردید مثل این :

function __construct()
{
if(self::$cacheDir===null)
self::$cacheDir = dirname(__FILE__).'/cache/';

if( ! file_exists(self::$cacheDir.'index.php'))
{
@mkdir(self::$cacheDir, 0777);
$fp = fopen(self::$cacheDir.'index.php', "wb");
if (!$fp)
die('eroor in make cache dir file in file ~ `'. __FILE__ .'` and line `'.__LINE__ .'`');
fwrite($fp, '<?php die; ?>');
fclose($fp);
}
return self::$ins;


بعد موقع استفاده خیلی راحت میگید :


$cache->add();

اگر مورد خاصی توی استفاده به این صورت هست لطفا به من بگید .