I manage a rather large traffic website. On each page we keep track of a visitors online by running the following code. We then have a cron which deletes the records which are older than X minutes.
if(!isset($_SESSION[users_online_id])) {
if(!(date('H')=='02' && date("i") >= 37 && date("i") <= 45)) {
# NEW VISITOR - DOESN'T HAVE A USER_ONLINE_ID
$update_query = "INSERT INTO online SET
ip_address = '".$visitors_ip_address."',
datetime = now(),
user_id = ".$visitor_id.",
page = '".escape($_SERVER[REQUEST_URI])."',
area = '".$this_area."',
type = ".$visitor_type;
mysql_query($update_query);
# SET THEIR SESSION VAR FOR NEXT PAGE CHECKING
$_SESSION[users_online_id] = mysql_insert_id();
}
}
else{
# USER HAS A SESSION
# CHECK THAT THE RECORD STILL EXIST
$check_record = "SELECT COUNT(1) FROM online WHERE id = ".$_SESSION[users_online_id];
$check_record = mysql_query($check_record);
if(mysql_result($check_record,0) > 0){
# IF RECORD STILL EXISIT ( WAS NOT DELETED) UPDATE IT
$update_query = "UPDATE online SET
datetime = now(),
user_id = ".$visitor_id.",
page = '".escape($_SERVER[REQUEST_URI])."',
type = '".$visitor_type."',
area = '".$this_area."',
ip_address= '".$visitors_ip_address."'
WHERE id = '".$_SESSION[users_online_id]."'";
mysql_query($update_query);
}
else if(!(date('H')=='02' && date("i") >= 37 && date("i") <= 45)){
# IF RECORD WAS DELETED (TO LONG ON 1 PAGE), INSERT A NEW RECORD
$update_query = "INSERT INTO online SET
ip_address = '".$visitors_ip_address."',
datetime = now(),
user_id = ".$visitor_id.",
page = '".escape($_SERVER[REQUEST_URI])."',
area = '".$this_area."',
type = ".$visitor_type;
mysql_query($update_query);
$_SESSION[users_online_id] = mysql_insert_id();
}
}
Doing some performace monitoring, i have noticed that queries which interact with this table are starting to take a lot longer to execute. Any ideas on how this can be improved?
You may eliminate SELECT query and use UPDATE query and mysql_affected_rows() function.
Small point but...
$_SERVER['REQUEST_URI'] is 7x faster than $_SERVER[REQUEST_URI]
Also make sure id is set up as the primary key.
Related
I have a php API where i am checking different conditions and based on that, i am fetching the count of the row and updating the count in the same table.
Below are the Conditions i am writing the query: (Note: 1 user can have multiple campaigns)
1) For a given user(Uid), for a particular campaign whose type = Impression, i am getting the Impression count and updating the same in table
2) For a given user(Uid), for a particular campaign whose type = Action i am getting the Action count and updating the same in table
//To get the Impression/Action/Lead count
$Impressionarr = [];
$Actionarr = [];
//IMPRESSION COUNT
$imp_qry = "select count(*) as ImpressionCount from ClicksAndImpressions where Uid = 101642 and CampaignID =100 and Type='Impression' ;";
$impData = $this->getClicksAndImpressionsTable()->CustomQuery($imp_qry);
if($impData[0]['ImpressionCount'] != '' || $impData[0]['ImpressionCount'] !=NULL ){
$impr_update = "UPDATE ClicksAndImpressions SET ImpressionCount = ". $impData[0]['ImpressionCount'] ." where Uid = 101642 and CampaignID =100 ;";
}else{
echo '----not Present';
}
//Impression count
foreach($impData as $key=>$data)
{
$data['ImpressionCount'];
$Impressionarr[] = $data;
}
//ACTION COUNT
$action_qry = "select count(*) as ActionCount from ClicksAndImpressions where Uid = 101617 and CampaignID =81 and Type = 'Action';";
$actionData = $this->getClicksAndImpressionsTable()->CustomQuery($action_qry);
if($actionData[0]['ActionCount'] != '' || $actionData[0]['ActionCount'] !=NULL ){
$action_update = "UPDATE ClicksAndImpressions SET ActionCount = ". $actionData[0]['ActionCount'] ." where Uid = 101617 and CampaignID =81 ;";
$actionData = $this->getClicksAndImpressionsTable()->CustomUpdate($action_update); //print_r($actionData);exit;
}else{
echo '----not Present';
}
//Action count
foreach($actionData as $key=>$data)
{
$data['ActionCount'];
$Actionarr[] = $data;
}
//Trying to combine the 3 arrays- but 2nd and 3rd not merging into 1st
$combine = array_merge($CampaignDetailsarr,$Impressionarr,$Actionarr);
1) Can the above duplicates - either in Update query or multiple for loops be avoided. if so how to optimize the above as per my conditions
ie) For
if( Uid = 123 for some campaignId = 11 and if type is 'Impression')
-> Update query for impression
else if(Uid = 123 for campaignId= 22 and if type = 'something else')
-> Update query for something else
2) I already have one array 1. I need to merge my 2 new arrays (Impressionarr[], Actionarr[]) into the 1st one, but below is how im getting.
Expected:
Coming as:
You could probably speed it up by creating a stored procedure in your database and calling that with the required data. From what I can see, most of the logic you have to do can be done in the stored procedure.
I am new to php so far i wrote this referral script:
<?php
ob_start();
include( $_SERVER['DOCUMENT_ROOT'] . '/config.php' );
mysql_connect(DB_HOST,DB_USER,DB_PASS);
mysql_select_db(DB_NAME);
$id = $_REQUEST['id'];
$uid = $_REQUEST['uid'];
$oid = $_REQUEST['oid'];
$new = $_REQUEST['new'];
$total = $_REQUEST['total'];
$sig = $_REQUEST['sig'];
// Secrete Key
$hash = 'myapikey';
// Output results
if ($sig == $hash) {
//Users point update query here (it's working )
$users = mysql_query("SELECT points FROM users WHERE id=".$uid);
$rows = mysql_fetch_array($users);
$user_points = $rows['points'];
$query1 = mysql_query("update users set points=($user_points+$new) where id=".$uid );
//Updating referral coins (it's not working )
$query2 = ("SELECT points, referral_id, level FROM users WHERE referral_id=".$uid );
$user_rows = mysql_query($query2);
$all=mysql_fetch_array($user_rows,MYSQL_BOTH);
if($all['referral_id'] != 0 && $all['level'] == 0){
$lvl0 = $new*(15/100);
$referal_points = $lvl0;
$update_referral_points = ("update users set points = points + $referal_points where referral_id = ".$all['referral_id']);
mysql_query($update_referral_points);
} else if($all['referral_id'] != 0 && $all['level'] == 1){
$lvl1 = $new*(25/100);
$referal_points = $lvl1;
$update_referral_points = ("update users set points = points + $referal_points where referral_id = ".$all['referral_id']);
mysql_query($update_referral_points);
}
print "1\n";
} else {
print "0\n";
}
?>
How Script working:
whenever someone signup using referral code i have insert referral code user id into new user referral_id row, & through $_REQUEST['']; my app sending points ($new) to user...
$query1 is working fine there's problem to execute $query2, in short $query2 needs to be fixed; something getting wrong, that i am not able to figure out if any pro can help me out this i will appreciate it...
DB structure:
users table:
id (AI) name points Referral code Referral id Level
=========== ========== ========== ================== ============== ======
1 user A 0 abcdef123 0 0
2 user B 100 bvsuda897 1 1
3 user C 500 vrtasio65 2 0
In this example above,
1- user C signup using user B Referral code = bvsuda897
2- right now user B level is 1 so whenever user C earn point ($new) my app should give user B 25% coins of user C $new
The Problem
right now when my app sending coins to user C, user B not getting coins, because something wrong in query2
After spending some more time looking over your code, I have tracked down your issue. First, you need to get the referral_id from the $users query.
$users = mysql_query("SELECT points, referral_id FROM users WHERE id=".$uid);
Then $query2 needs to match the id to the user's referral_id, not the other way around.
$query2 = "SELECT id, points, referral_id, level FROM users WHERE id=".$rows['referral_id'];
Your UPDATE queries may need some work after that, but this will get you in to the if else conditions.
Successful code determined by OP
//Updating referral coins
$query2 = "SELECT id, points, referral_id, level FROM users WHERE id=".$rows['referral_id']; $user_rows = mysql_query($query2);
$all=mysql_fetch_array($user_rows,MYSQL_BOTH);
$lvl0 = intval((5/100) * $new);
$lvl1 = intval((10/100) * $new);
$query3 = mysql_query("update users set points = (points + $lvl0) where level = 0 AND referral_id = ".$all['referral_id']);
$query4 = mysql_query("update users set points = (points + $lvl1) where level = 1 AND referral_id = ".$all['referral_id']);
Now I appreciate that you are in the learning stage, but I want to point out a couple things that will cause confusions as you pursue PHP programming in the future.
First off, as Option mentioned, the MySQL functions you are using have been deprecated. They do not exist in the current stable version of PHP, and your code will no longer work if the server is updated. Look in to MySQLi or PDO as alternatives. It's a lot to learn, but some Googling will get you some guidance.
Second is your use of $_REQUEST, which combines the values of $_GET, $_POST and $_COOKIE, allowing easy manipulation by visitors. It may be that you are only using it for the user details while testing your other code, but I just want to make sure you know about PHP sessions, which is the better way to store a relationship between a logged in user and their persistent variables.
WRT: how to insert records for top 10 enteries only
This is more refined question.
I have gathered top 10 users for specific task. Using the query given below.
mysql_query("SELECT `userid`, SUM(`points`) as `total` FROM
`tablename` GROUP BY `userid` ORDER BY total DESC LIMIT 10");
Now , I need to award bonues to the top 3 gathered users only, out of these selected top 10. I am not getting the idea , on how to write query for this purpose.
The top 3 bonuses are different for top 3
1: First user gets 1000 points
2: 2nd user gets 500 points
3: 3rd user gets 100 points
I need to update one field in tablename = user , field name = points.
To update the bonus i am using the below query(general query):
$Db1->query('UPDATE user SET points=points+'.$rate.'
WHERE userid = '.$credituser);
I hope this question is well elaborated as per the community standards.
Kindly guide.
Working on a pure MySQL version.
As you've PHP tagged, I'll incorporate that into my answer :)
(Ps: Don't use mysql_*. As OP used mysql_*, my answer will)
Fetch the results
Loop through the results
Update the results depending on their position
$objGet = mysql_query("SELECT `userid`, SUM(`points`) as `total` FROM
`tablename` GROUP BY `userid` ORDER BY total DESC LIMIT 10");
if( mysql_num_rows($objGet) ) {
$intIteration = 1;
while( $arrResults = mysql_fetch_assoc($objGet) ) {
switch($intIteration) {
case 1 :
mysql_query("UPDATE tablename SET points = points + 1000 WHERE userid = ". $arrResults['userid']);
break;
case 2 :
mysql_query("UPDATE tablename SET points = points + 500 WHERE userid = ". $arrResults['userid']);
break;
case 3 :
mysql_query("UPDATE tablename SET points = points + 100 WHERE userid = ". $arrResults['userid']);
break;
default:
//No idea.
//Not in the top 3.
break;
}
$intIteration++;
}
} else {
//No users.
}
Currently, I have the following PHP code loaded every time the page is refreshed. I am trying to update the views column +1 every time the page is loaded. To do this, I first retrive the previous views value from the table, then run another query to add + to that number. The problem that is occurring is every time I refresh the page, The code somehow adds two instead of 1. So instead of the $viewsA variable increasing by +1, it is increasing by +2.
$query = mysql_query("SELECT * FROM Games WHERE pagename = '$game' ");
WHILE($datarows = mysql_fetch_array($query)):
$title = $datarows['title'];
$description = $datarows['desc'];
$img_url = $datarows['img'];
$cat = $datarows['cat'];
$pagename = $datarows['page'];
$rating = $datarows['rat'];
$viewsA = $datarows['view_count'];
$gameid = $datarows['id'];
endwhile;
$updateviews = $viewsA +1;
mysql_query("UPDATE `trainw_games`.`Games` SET `view_count` = '$updateviews' WHERE `Games`.`id` = $gameid;");
What do I need to change to make it only add +1 to the views column?
I don't think that a while loop is appropriate for this problem. I would recommend to echo $viewsA . '-' . $updateviews; to see what the value is before and after the add.
But, why not just run a single UPDATE statement?
UPDATE Games SET view_count = view_count + 1 WHERE Games.id = $gameid
Of course, you should stop using mysql_ functions and use either MySQLi or PDO:
$stmt = $mysqli->prepare("UPDATE Games SET view_count = view_count + 1 WHERE Games.id = ?");
$stmt->bind_param($gameid);
$stmt->execute();
$stmt->close();
Do you have multiple rows in your database? If yes, it maybe caused by overriding the previous value.
For example:-
If first row the view_count is 1.
While the second row view_count is 2.
that overrides the the first row with 2 + 1 = 3
Which makes you thought increased by 2?
UPDATE 1:
Ok, try this, put this
$updateviews1 = $viewsA + 1;
if ($viewsA < $updateviews1) { //execute the viewsA + 1 }
I am using a table in MySQL called "submissions" that contains fields called "loginid" and "datesubmitted." "Loginid" is an integer and "datedubmitted" is a timestamp.
I would like to make a function that will determine whether or not a given "$uid" equals a "loginid" that has 11 or more rows in "submissions" with a "datesubmitted" of today's calendar date.
I'm not sure how to make this, but this is what I have so far:
function uidlimit($uidinput){
$queryuid = "select uid from submission where datesubmitted > '$todaysDate 00:00' and date < '$todaysDate 23:59' group by uid having count() > 11";
$uidresult = mysql_query($queryuid);
Any advice on how I can make such a function?
Thanks in advance,
John
EDIT: Thanks to Pekka, I ended up using this, which works:
$queryuidcount = "select loginid from submission where TO_DAYS(datesubmitted) = TO_DAYS(NOW()) AND loginid = '$uid'"; // Remove line breaks
$uidresult = mysql_query($queryuidcount);
if (mysql_num_rows($uidresult) >= 11)
{
session_write_close();
header("Location:http://www.domain.com/sample/index.php");
exit;
}
Why not simply get the number of submissions for the given user, and count them in PHP?
function uidlimit($uidinput){
$uidinput = mysql_real_escape_string($uidinput); // Don't forget to sanitize!
$queryuid = "select count(uid) as cnt from submission
where TO_DAYS(datesubmitted) = TO_DAYS(NOW())
AND uid = '$uidinput'"; // Remove line breaks
$uidresult = mysql_query($queryuid);
$record = mysql_fetch_row($uidresult);
if ($record->cnt >= 11) echo "11 or more!";
else echo "less than 11!";