Query Improvement mysql - php

Hi Guys i have this query and it is super slow.
If you can understand the code how can i possibly combine the two queries into one
or how can i possibly make this query faster.
this is the code
$strSQL = "SELECT user_status_history.*, queues_config.extension FROM user_status_history ";
$strSQL .= "LEFT JOIN queues_config ON user_status_history.skillset = REPLACE(queues_config.grppre, \":\", \"\") ";
$strSQL .= "WHERE user_status_history.status_id = 9 "; # outbound call
$strSQL .= "AND DATE_FORMAT(status_time, '%Y-%m-%d') = '$check_date' ";
if ($i==1)
$strSQL .= "AND TIME_FORMAT(status_time, '%H:%i') >= '$cboHrFrom:$cboMinFrom' ";
else if (strtotime($check_date) == strtotime($end_date))
$strSQL .= "AND TIME_FORMAT(status_time, '%H:%i') <= '$cboHrTo:$cboMinTo' ";
$strSQL .= "AND queues_config.extension = '$cboSkillSet' ";
if ($cboGroup!='' && $strAgentGroup!='') $strSQL .= "AND user_status_history.user_id IN (".$strAgentGroup.") ";
$strSQL .= "ORDER BY user_status_history.user_id, user_status_history.status_time ";
$rs2 = &$cn->Execute($strSQL);
while (!$rs2->EOF)
{
$strSQL = "SELECT status_time, time_to_sec(timediff(status_time, '".$rs2->fields['status_time']."')) AS timesecs FROM user_status_history ";
$strSQL .= "LEFT JOIN queues_config ON user_status_history.skillset = REPLACE(queues_config.grppre, \":\", \"\") ";
$strSQL .= "WHERE status_time > '".$rs2->fields['status_time']."' ";
$strSQL .= "AND user_id = '".$rs2->fields['user_id']."' ";
$strSQL .= "AND queues_config.extension = '".$rs2->fields['extension']."' ";
$strSQL .= "ORDER BY status_time LIMIT 1;";
$rs3 = &$cn->Execute($strSQL);
if (!$rs3->EOF)
{
$sum_talk_sec = $sum_talk_sec + $rs3->fields['timesecs'];
}
$rs3->Close();
$rs2->MoveNext();
}
$rs2->Close();

1
Check out there are table indexes for
user_status_history.status_id
user_status_history.user_id
2
these are difficult for optimizer. Try get rid of these
LEFT JOIN queues_config ON user_status_history.skillset = REPLACE(queues_config.grppre, \":\", \"\") ";
LEFT JOIN queues_config ON user_status_history.skillset = REPLACE(queues_config.grppre, \":\", \"\") ";
3
Get rid of the loop query.
Fetch all IDs from query1 to an array and create one query for them all:
"SELECT user_id, status_time, time_to_sec(timediff(status_time, '".$rs2->fields['status_time']."')) AS timesecs FROM user_status_history ";
...
AND user_id IN (id1, id2, id3 ... )
4 (From DCOder )
Convert these the other way around. Use PHP to create mysql datetime fields.
$strSQL .= "AND DATE_FORMAT(status_time, '%Y-%m-%d') = '$check_date' ";
-- >
preg_match('/^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$/', $check_date, $regs );
$enddate = date('Y-m-d', mktime( $hour=6, $min=0, $sec=0, $mon=$regs[2], $day=$regs[3]+1, $year=$regs[1] ));
$strSQL .= " AND status_time > '$check_date' AND status_time <= '$enddate' ;
$strSQL .= "AND TIME_FORMAT(status_time, '%H:%i') >= '$cboHrFrom:$cboMinFrom' ";
-- > $strSQL .= " AND status_time >= '$check_date $cboHrFrom:$cboMinFrom:00' ";
$strSQL .= "AND TIME_FORMAT(status_time, '%H:%i') <= '$cboHrTo:$cboMinTo' ";
-- > $strSQL .= " AND status_time <= '$check_date $cboHrTo:$cboMinTo:59' ";

Related

Where clause stopped working

I have this code that (without the WHERE, was working) How do I get it to work with the WHERE clause ?
I just need it to only list lines that is current and max 2 years ahead.
$SQL = "SELECT ";
$SQL .= "SUM(Bookings.Spots) as SUMSPOT, Trips.ID, Bookings.FK_ID, Trips.MaxSpots, ";
$SQL .= "Trips.Tripnr, Trips.StartDate, Trips.EndDate, Trips.StartLocation, ";
$SQL .= "Trips.DestinationDK, Trips.PricePerSpot ";
$SQL .= "FROM Trips WHERE Trips.EndDate >= NOW() AND Trips.EndDate < DATE_ADD(NOW(), INTERVAL 2 YEAR) ";
$SQL .= "LEFT JOIN Bookings on Bookings.FK_ID = Trips.ID ";
$SQL .= "GROUP BY Trips.ID, Bookings.FK_ID ORDER BY Trips.StartDate ASC ";
You need to add the WHERE clause after the LEFT JOIN and before the GROUP tag.
You can check the documentation here for more answers as to where you can put which keyword.

Why mysql sql query is taking long time to get the result?

In mysql db table contact_details I have almost 12,000 rows and it's continuously updating.
Now I have a search form where I need to search data from the db table contact_details
For e.g : I am searching 2 in type column from contact_details table and there are almost 11,000 records of 2.
In this situation, my sql query is taking long time to produce result ! Sometime it's showing me Maximum time exceed. What should I do to get the result more quickly ?
Here is the contact_details table look like :
Here is the search form look like with error message :
I am using following sql query to get the search result :
if(!empty($ad_keyword)) {
$getSearch = "SELECT * FROM (SELECT GROUP_CONCAT(DISTINCT keywordName ORDER BY keywordName) as keywordName, ";
}
else{
$getSearch = "SELECT ";
}
$getSearch .= " cd.cdid, cd.family_name, cd.given_name, cd.department, cd.title, company.*, users.nickname, contact_label.label_data FROM
contact_details as cd
LEFT JOIN users ON users.user_id = cd.user_id
LEFT JOIN company ON company.cid = cd.cid
LEFT JOIN contact_docs ON contact_docs.cdid = cd.cdid
LEFT JOIN userkeywords ON userkeywords . cdid = cd . cdid
LEFT JOIN keywords ON keywords . kid = userkeywords . kid
LEFT JOIN contact_label ON contact_label.cdid = cd.cdid
WHERE 1=1 ";
if(!empty($ad_company)){
$getSearch .= "AND company.company_name LIKE '$ad_company%' ";
}
if(!empty($ad_fname)){
$getSearch .= "AND cd.family_name LIKE '$ad_fname%' ";
}
if(!empty($ad_department)){
$getSearch .= "AND cd.department LIKE '$ad_department%' ";
}
if(!empty($ad_mp)){
$getSearch .= "AND cd.mp >= '$ad_mp' ";
}
if(!empty($ad_e2)){
$getSearch .= "AND cd.e2 >= '$ad_e2' ";
}
if(!empty($ad_pl)){
$getSearch .= "AND cd.pl >= '$ad_pl' ";
}
if(!empty($ad_ap)){
$getSearch .= "AND cd.ap >= '$ad_ap' ";
}
if(!empty($ad_j2)){
$getSearch .= "AND cd.j2 >= '$ad_j2' ";
}
if(!empty($ad_agreater)){
$getSearch .= "AND cd.age >= '$ad_agreater' ";
}
if(!empty($ad_aless)){
$getSearch .= "AND cd.age <= '$ad_aless' ";
}
if(!empty($ad_agreater) && !empty($ad_aless)){
$getSearch .= "AND cd.age BETWEEN '$ad_agreater' AND '$ad_aless'";
}
if(!empty($ad_sgreater)){
$getSearch .= "AND cd.comp >= '$ad_sgreater' ";
}
if(!empty($ad_sless)){
$getSearch .= "AND cd.comp <= '$ad_sless' ";
}
if(!empty($ad_sgreater) && !empty($ad_sless)){
$getSearch .= "AND cd.comp BETWEEN '$ad_sgreater' AND '$ad_sless'";
}
if(!empty($ad_noteterm)){
$ad_noteterm = preg_replace("/\{ASUSIBBIR\}(.+?)\s:\s(.+?)\{ASUSIBBIR\}/m", "$2", $ad_noteterm);
$getSearch .= "AND LOCATE('$ad_noteterm', REPLACE (notesUpdate, '{ASUSIBBIR}', ' '))";
}
if(!empty($ad_cnote)){
$getSearch .= "AND LOCATE('$ad_cnote', cd.characterNotes)";
}
if(!empty($ad_twork)){
$getSearch .= "AND contact_label.label_data LIKE '%$ad_twork%'";
}
if(!empty($ad_tmobile)){
$getSearch .= "AND cd.mobile_phone like '%$ad_tmobile%'";
}
if(!empty($ad_resume)){
$getSearch .= "AND LOCATE('$ad_resume', contact_docs.file_content)"; //is this the resume? yes
}
if(!empty($ad_datefrom) && empty($ad_dateto)){
$getSearch .= "AND cd.created_date BETWEEN '$ad_datefrom'AND '$date'";
}
if(!empty($ad_dateto) && empty($ad_datefrom)){
$getSearch .= "AND cd.created_date BETWEEN date('0000-00-00') AND '$ad_dateto' ";
}
if(!empty($ad_datefrom) && !empty($ad_dateto)){
$getSearch .= "AND cd.created_date BETWEEN '$ad_datefrom' AND '$ad_dateto'";
}
if(!empty($ad_type)){
$getSearch .= "AND cd.type = '$ad_type' ";
}
if(!empty($ad_wemail)){
$getSearch .= "AND cd.email LIKE '$ad_wemail%'";
}
if(!empty($ad_pemail)){
$getSearch .= "AND cd.email_private LIKE '$ad_pemail%'";
}
if(!empty($ad_title)){
$getSearch .= "AND cd.title LIKE '$ad_title%'";
}
if(!empty($ad_source)){
$getSearch .= "AND cd.source LIKE '$ad_source%'";
}
if(!empty($ad_consultant)){
$getSearch .= "AND users.nickname LIKE '%$ad_consultant%'";
}
if(!empty($ad_keyword)){
$ad_keyword_param = str_replace(",","','",$ad_keyword);
$getSearch .= " AND keywords.keywordName IN ('$ad_keyword_param') ";
}
$getSearch .= " GROUP BY cd.user_id, cd.cid, cd.cdid ";
if(!empty($ad_keyword)){
$ad_keyword_param = str_replace(",",",",$ad_keyword);
$getSearch .= " ) as a WHERE keywordName LIKE '$ad_keyword_param%' ";
}
Implement indexing
Instead of fetch '*' specify only the required column name.
instead of subquery try to use join
use 'limit' clause
First You need to do indexing with your all table like users,company etc...
about that error solving of fatal error please put below line in php script in first line
ini_set('max_execution_time', 0);

FULL TEXT search with normal search

Im trying to make a query that will do a full text search with 2 additional conditions. The full text part works fine. I tried these so far, and both are not working:
$query = "SELECT * FROM table ";
$query .= "WHERE MATCH(title) ";
$query .= "AGAINST('".$title."') ";
$query .= "AND state='".$state."' ";
$query .= "AND county='".$county."' ";
$query .= "LIMIT 5 ";
$query = "SELECT * FROM table ";
$query .= "WHERE MATCH(title) ";
$query .= "AGAINST('".$title."') ";
$query .= "MATCH(state) AGAINST('".$state."') ";
$query .= "MATCH(county) AGAINST('".$county."') ";
$query .= "LIMIT 5 ";
I just tried this from the comments, but I get an error 1064 near %$state%:
$query = "SELECT * FROM table ";
$query .= "WHERE MATCH(title) ";
$query .= "AGAINST('".$title."') ";
$query .= "AND state LIKE %".$state."% ";
$query .= "AND county LIKE %".$county."% ";
$query .= "LIMIT 5 ";
$query = "SELECT * FROM table ";
$query .= "WHERE title ";
$query .= "LIKE %".$title."% ";
$query .= "AND state LIKE %".$state."% ";
$query .= "AND county LIKE %".$county."% ";
$query .= "LIMIT 5 ";

Search for user in 3 different tables that have different columns

I'm having a hell of a time with this. I have 3 tables of users. They are in different tables because they have different columns depending on the type of user they are.
Now to log in to the site I'm trying to select the user's email and all the other values that correspond to him. Based on some feedback from other users here I wrote my query like this:
$query = "SELECT id, position_id, first_name, last_name, email ";
$query .= "FROM pims ";
$query .= "WHERE email = '{$email}' ";
$query .= "AND hashed_password = '{$hashed_password}' ";
$query .= "AND com_code IS NULL ";
$query .= "LIMIT 1 ";
$query .= "UNION ALL SELECT id, district_id, position_id, first_name, last_name, email ";
$query .= "FROM dms ";
$query .= "WHERE email = '{$email}' ";
$query .= "AND hashed_password = '{$hashed_password}' ";
$query .= "AND com_code IS NULL ";
$query .= "LIMIT 1 ";
$query .= "UNION ALL SELECT * ";
$query .= "FROM users ";
$query .= "WHERE email = '{$email}' ";
$query .= "AND hashed_password = '{$hashed_password}' ";
$query .= "AND com_code IS NULL ";
$query .= "LIMIT 1";
But I get a "Database query failed" message. The query worked fine when I had only one SELECT statement, so I know it's this query that's not working. Any ideas how to fix it?
Doing union all should have the same number of columns in all queries.
$query = "SELECT id, 'garbage_data' AS district_id, position_id, first_name, last_name, email ";
$query .= "FROM pims ";
$query .= "WHERE email = '{$email}' ";
$query .= "AND hashed_password = '{$hashed_password}' ";
$query .= "AND com_code IS NULL ";
$query .= "LIMIT 1 ";
$query .= "UNION ALL ";
$query .= "SELECT id, district_id, position_id, first_name, last_name, email ";
$query .= "FROM dms ";
$query .= "WHERE email = '{$email}' ";
$query .= "AND hashed_password = '{$hashed_password}' ";
$query .= "AND com_code IS NULL ";
$query .= "LIMIT 1 ";
$query .= "UNION ALL ";
$query .= "SELECT id, district_id, position_id, first_name, last_name, email ";
$query .= "FROM users ";
$query .= "WHERE email = '{$email}' ";
$query .= "AND hashed_password = '{$hashed_password}' ";
$query .= "AND com_code IS NULL ";
$query .= "LIMIT 1";
In case you have a missing column. You can add none existent data like:
'garbage_data' AS district_id
This will show a string garbage_data which is just there to make the column count the same.
It can be anything, It can even be '' AS district_id.
First off the number and type of columns need to be the same in a union query. Second I would suggest you to make a view for that and then use the view for convenience since I don't think this is the only spot you will need such a query.
$query = "SELECT id, '' as district_id, position_id, first_name, last_name, email ";
$query .= "FROM pims ";
$query .= "WHERE email = '{$email}' ";
$query .= "AND hashed_password = '{$hashed_password}' ";
$query .= "AND com_code IS NULL ";
$query .= "LIMIT 1 ";
$query .= "UNION ALL SELECT id, district_id, position_id, first_name, last_name, email ";
$query .= "FROM dms ";
$query .= "WHERE email = '{$email}' ";
$query .= "AND hashed_password = '{$hashed_password}' ";
$query .= "AND com_code IS NULL ";
$query .= "LIMIT 1 ";
$query .= "UNION ALL SELECT id, district_id, position_id, first_name, last_name, email ";
$query .= "FROM users ";
$query .= "WHERE email = '{$email}' ";
$query .= "AND hashed_password = '{$hashed_password}' ";
$query .= "AND com_code IS NULL ";
$query .= "LIMIT 1";

Mysql statement works when run directly but doesn't in my php file

When i run this code in mysql workbench it works but in my php it only returns an empty array.
<?PHP
session_start();
$results = array();
if( $query = $db->query("SELECT business_id, BusinessName, date, post ".
"FROM WolfeboroC.posts ".
"JOIN WolfeboroC.users ON users.recid = posts.business_id ".
"WHERE City= '$city' AND State='$state'".
"ORDER BY date DESC LIMIT 0, 500") )
{
while($record = $query->fetch_assoc())
{
$results[] = $record;
}
$query->close();
}
echo json_encode($results);
?>
Firstly, you can't use the structure
FROM
WHERE
JOIN
You have to use
FROM
JOIN
WHERE
Secondly, you are missing a space at the end of '$state'"
"FROM WolfeboroC.posts ". "WHERE city= '$city' && state='$state'".
"JOIN WolfeboroC.users ON users.recid = posts.business_id ".
So I'm pretty sure that doesn't really work on MySQL, as you mentioned.
There are also some PHP errors. Use this code:
if($result = $db->query(
"SELECT business_id, BusinessName, date, post ".
"FROM WolfeboroC.posts ".
"JOIN WolfeboroC.users ON users.recid = posts.business_id ".
"WHERE City= '$city' AND State='$state' ".
"ORDER BY date DESC LIMIT 0, 500")) {
while($record = $result->fetch_assoc()) {
$results[] = $record;
}
$result->close();
}

Categories