PHP Loading times - php

The following query take 10.86secs to initiate,
$sql="SELECT items.id i_id, status,manufacturerid,model,label,cpuno,corespercpu
from items,item2soft
where item2soft.itemid=items.id AND item2soft.softid={$r['id']}
order by label asc ";
While this code takes 23.73secs
$sql="SELECT items.id i_id, status,manufacturerid,model,label,cpuno,corespercpu
from items,item2soft
where item2soft.itemid=items.id AND item2soft.softid={$r['id']}";
The only difference between two codes is the latter has a ORDER BY keyword.Is there any way to make it faster.Please feel free to ask me anything.thanks for your help :)

After looking at your query - and by that I mean: adding proper indenting so I can actually read it - you probably just need to add some indexes.
$sql = "SELECT
items.id i_id,
status,
manufacturerid,
model,
label,
cpuno,
corespercpu
FROM
items,
item2soft
WHERE
item2soft.itemid = items.id
AND item2soft.softid = {$r['id']}
ORDER BY label ASC"
Add indexes on item2soft.itemid and item2soft.softid
If it's still slow, run an EXPLAIN

Related

Using PHP in MYSQL for order by with MariaDb

I'm trying to retrieve records in the order in which I think they are being accessed.
My code is as follows:
the data to search for:
$to_check="Yes_ij_affirmation', ',_cm', 'there_px_ex', 'is_vbz_1', '._fs";
the select statement:
$sql = "SELECT wd, wd_ps2, rt1, rt4, definition FROM august_2022 WHERE wd_ps2 IN ($to_check) order by ".$to_check."";
and the outcome is (I've put it in list form to make it easier to see v the original):
Yes_ij_affirmation
there_px_ex
._fs (should be last)
,_cm (should be second)
is_vbz_1 (should be third)
I'm not sure whether what I am trying to do is feasible, but would welcome advice.
WW
You need to add quotes in
$to_check
$to_check="'Yes_ij_affirmation', ',_cm', 'there_px_ex', 'is_vbz_1', '._fs'";
And the select statement should look like this:
$sql = "SELECT wd, wd_ps2, rt1, rt4, definition FROM august_2022 WHERE wd_ps2 IN ($to_check) order by " .$to_check;
You need quotes at the beginning and end of $to_check.
Then you can use the FIELD() function to order by the position in that list.
$to_check="'Yes_ij_affirmation', ',_cm', 'there_px_ex', 'is_vbz_1', '._fs'";
$sql = "SELECT wd, wd_ps2, rt1, rt4, definition
FROM august_2022
WHERE wd_ps2 IN ($to_check)
order by FIELD(wd_ps2, $to_check)"

How to merge two UPDATE queries into one, different WHERE and SET?

I was wondering if it's possible to combine these two queries as they do not work separately (one of the two only works). They are
$addquery = "UPDATE winners SET mem_name='$addname' WHERE mem_name='$deletename'";
$addresult= mysqli_query($connect, $addquery);
$query = "UPDATE winners INNER JOIN members SET winners.mem_id = members.mem_id
WHERE winners.mem_name = members.mem_name";
$result = mysqli_query($connect, $query);
Can this be done in just one query? Thank you!!!
I am not saying you should do it, but judging from the flow of the code you provided, this is how you could do it.
UPDATE winners w
SET w.mem_name = '$addname'
, w.mem_id = IFNULL(SELECT m.mem_id
FROM members AS m
WHERE m.mem_name = '$addname'
ORDER BY m.mem_id DESC
LIMIT 1
, w.mem_id
)
WHERE w.mem_name = '$deletename'
;
Note, the ORDER BY is technically optional; your question does not state whether mem_name is guaranteed unique in members. If it is unique, the order by should not be needed; if it is not, it at least adds some consistency to the expected value retrieved.
If you have control over the database design, I would suggest removing mem_name from winners altogether. It is/would be redundant data if you were managing the relation primarily by mem_id to begin with.

MYSQL define certain column in mysql_query array?

When I'm selecting from multiple tables that share column names is there a way I can return both, but define which one I want to select the data from?
For instance:
Both tables contain "date" columns, and I want to use both, but I would like to avoid having to rename each column that has duplicate names.
$query = mysql_query("SELECT * FROM posts, comments"); //(SELECT * is just for example)
while($row=mysql_fetch_array($query))
{
$postDate = $row['date']; //I would like to be able to do something like:
//$postDate = $row['posts']['date']; OR $row['posts.date'];
//of course it's all in an array now, jumbled up.
$commentDate = $row['date'];
}
You need to alias the duplicate column names in your query if you want both, eg
SELECT p.date AS postDate, c.date AS commentDate
FROM posts p, comments c
Then use the aliases to retrieve the values
$postDate = $row['postDate'];
$commentDate = $row['commentDate'];
FYI, it's almost never a good idea to SELECT *, especially when multiple tables are involved. You should always try to be specific about the columns added to your SELECT clause
The best way to do this is to specify the fields in the query itself, giving aliases to them:
SELECT posts.date postDate, comments.date commentDate FROM posts, comments;
It's generally frowned upon to use SELECT *. You end up with code that's a little less stable. By specifying the exact fields, and the aliases of those fields, you are less prone to bugs that might arise from changes to the database schema, etc.
Just add aliases...btw, you should never use SELECT * FROM ...
$query = mysql_query("SELECT posts.date as pdate, comments.date as cdate FROM posts, comments");
while($row=mysql_fetch_array($query))
{
$postDate = $row['pdate'];
$commentDate = $row['cdate'];
}

Limit SQL join when using CodeIgniter active record class

I'm getting a product listing. Each product may have 1 or more image, I only want to return the first image.
$this->db->select('p.product_id, p.product_name i.img_name, i.img_ext');
$this->db->join('products_images i', 'i.product_id = p.product_id', 'left');
$query = $this->db->get('products p');
Is there anyway to limit the db->join to 1 record using the CI active record class?
Add $this->db->limit(1); before calling $this->db->get('products p');. See the docs at ellislab.com: search the page for limit.
EDIT: I misread the fact that you were trying to apply the LIMIT to the internal JOIN statement.
No. Since you can not do a LIMIT on an internal JOIN statement in regular SQL you can not do it with Code Igniter's ActiveRecord class.
You can achieve what you want using $this->db->group_by with a left join:
$this->db->select('products.id, products.product_name, products_images.img_name, products_images.img_ext');
$this->db->from('products');
$this->db->join('products_images', 'products_images.product_id = products.id', 'left');
$this->db->group_by('products.id');
$query = $this->db->get();
This should give you results by products.id (without repetition of products), with the first matching record from products_images joined to each result row. If there's no matching row from the joined table (i.e. if an image is missing) you'll get null values for the products_images fields but will still see a result from the products table.
To expand on #Femi's answer:
There's no good way to limit the JOIN, and, in fact, you don't really want to. Assuming both products_image.product_id and products.id have indexes (and they absolutely should if you're going to join against them repeatedly) when the database engine does a join, it uses the indexes to determine what rows it needs to fetch. Then the engine uses the results to determine where on the disk to find the records it needs. If you
You should be able to see the difference by running these SQL statements:
EXPLAIN
SELECT p.product_id, p.product_name, i.img_name, i.img_ext
FROM products p
LEFT JOIN products_images i
ON i.product_id = p.product_id
as opposed to:
EXPLAIN
SELECT p.product_id, p.product_name, i.img_name, i.img_ext
FROM (SELECT product_id, product_name FROM products) p
LEFT JOIN (SELECT img_name, img_ext FROM products_images) i
ON i.product_id = p.product_id
The first query should have an index, the second one will not. There should be a performance difference if there's a significant number of rows the the DB.
Had this issue too the way I solved it was iterating over the results and removing the current object if the product_id had existed in a previous one. Create a array, push the product_id's to it while checking if they are repeats.
$product_array = array();
$i = 0;
foreach($result as $r){
if(in_array($r->product_id,$product_array)){
unset($result[$i]);
}else{
array_push($product_array,$r->product_id);
}
$i++;
}
$result = array_values($result); //re-index result array
Now $result is what we want

Joining 2 mysql queries

I have two tables which I need to select all rows from where the userid is $userid then sort them. I tried to use join but I couldn't even really get started on how to get it right. Can anybody point me in the right direction as to how to make these into one query?
$result1 = mysql_query("SELECT * FROM paypal_sub_info
WHERE userid='$THEuserid' ORDER BY cur_time DESC");
$result2 = mysql_query("SELECT * FROM paypal_pay_info
WHERE userid='$THEuserid' ORDER BY cur_time DESC");
while($row = mysql_fetch_array($result1)){
echo $row['txn_type'];
}
Solution:
SELECT *
FROM paypal_sub_info sub,paypal_pay_info pay
WHERE pay.userid = '$THEuserid'
AND sub.userid = '$THEuserid'
ORDER BY pay.cur_time DESC,sub.cur_time DESC
Try this:
SELECT * FROM paypal_sub_info sub, paypal_pay_info pay
WHERE pay.userid='$THEuserid' AND sub.userid='$THEuserid'
ORDER BY pay.cur_time DESC, sub.cur_time DESC
If you just want 'txn_type', you could make it a SELECT pay.txn_type AS txn_type
Use:
SELECT psi,*, ppi.*
FROM PAYPAL_SUB_INFO psi
JOIN PAYPAL_PAY_INFO ppi ON ppi.userid = psi.userid
WHERE psi.userid = $THEuserid
ORDER BY psi.cur_time DESC, ppi.cur_time DESC
I believe you want:
SELECT field1, field2, ... FROM paypal_sub_info WHERE userid='$THEuserid'
UNION
SELECT field1, field2, ... FROM paypal_pay_info WHERE userid='$THEuserid'
ORDER BY cur_time DESC
So first off consider using mysqli for for any serious project. OMG Ponies answer is how I would suggest doing it, thought you shouldn't have to specify the alias.wildcard fields separately in the select clause. It's also a best practice to actually specify the fields you are trying to fetch rather than *, though we all use * a lot when we're lazy.
Will A's answer makes me smile because it's technically what you asked for, though not what I expect you wanted.
Do you have a more detailed description of what data you're trying to extract, or was this just an example because you are having trouble figuring out joins?
-J

Categories