I have 2 tables that have data in them, due to the size of the third table I don't want to run queries against it so I have created a secondary table with only product SKU and IDs.
Here is what I am trying to do but I am quite confused on where to start.
Optimistically there is a way to do this with a MySQL query and loop through all of the records.
if wp_stc_outofstock `product_number` == wp_stc_current_products `sku`
UPDATE wp_postmeta SET meta_value = 'outofstock' WHERE post_id = 'wp_stc_outofstock.product_number' AND meta_key = '_stock_status'
Any help is appreciated, I am sure I am not doing a great job explaining it.
My best attempt given your limited explanation -
UPDATE `wp_stc_outofstock` `oos`
JOIN `wp_stc_current_products` `cp`
ON `oos`.`product_number` = `cp`.`sku`
JOIN `wp_postmeta` `pm`
ON `oos`.`product_number` = `pm`.`post_id`
AND `pm`.`meta_key` = '_stock_status'
SET `pm`.`meta_value` = 'outofstock';
As #danblack suggested, perhaps you should be dealing with your performance concerns, particularly by looking at your indexing. As long as the tables are indexed appropriately, millions of rows is not an issue.
Related
I did not write this query. I am working on someone else's old code. I am looking into changing what is needed for this query but if I could simply speed up this query that would solve my problem temporarily. I am looking at adding indexes. when I did a show indexes there are so many indexes on the table orders can that also slow down a query?
I am no database expert. I guess I will learn more from this effort. :)
SELECT
orders.ORD_ID,
orders.ORD_TotalAmt,
orders.PAYMETH_ID,
orders.SCHOOL_ID,
orders.ORD_AddedOn,
orders.AMAZON_PurchaseDate,
orders.ORDSTATUS_ID,
orders.ORD_InvoiceNumber,
orders.ORD_CustFirstName,
orders.ORD_CustLastName,
orders.AMAZON_ORD_ID,
orders.ORD_TrackingNumber,
orders.ORD_SHIPPINGCNTRY_ID,
orders.AMAZON_IsExpedited,
orders.ORD_ShippingStreet1,
orders.ORD_ShippingStreet2,
orders.ORD_ShippingCity,
orders.ORD_ShippingStateProv,
orders.ORD_ShippingZipPostalCode,
orders.CUST_ID,
orders.ORD_ShippingName,
orders.AMAZON_ShipOption,
orders.ORD_ShipLabelGenOn,
orders.ORD_SHIPLABELGEN,
orders.ORD_AddressVerified,
orders.ORD_IsResidential,
orderstatuses.ORDSTATUS_Name,
paymentmethods.PAYMETH_Name,
shippingoptions.SHIPOPT_Name,
SUM(orderitems.ORDITEM_Qty) AS ORD_ItemCnt,
SUM(orderitems.ORDITEM_Weight * orderitems.ORDITEM_Qty) AS ORD_ItemTotalWeight
FROM
orders
LEFT JOIN orderstatuses ON
orders.ORDSTATUS_ID = orderstatuses.ORDSTATUS_ID
LEFT JOIN orderitems ON
orders.ORD_ID = orderitems.ORD_ID
LEFT JOIN paymentmethods ON
orders.PAYMETH_ID = paymentmethods.PAYMETH_ID
LEFT JOIN shippingoptions ON
orders.SHIPOPT_ID = shippingoptions.SHIPOPT_ID
WHERE
(orders.AMAZON_ORD_ID IS NOT NULL AND (orders.ORD_SHIPLABELGEN IS NULL OR orders.ORD_SHIPLABELGEN = '') AND orderstatuses.ORDSTATUS_ID <> 101 AND orderstatuses.ORDSTATUS_ID <> 40)
GROUP BY
orders.ORD_ID,
orders.ORD_TotalAmt,
orders.PAYMETH_ID,
orders.SCHOOL_ID,
orders.ORD_AddedOn,
orders.ORDSTATUS_ID,
orders.ORD_InvoiceNumber,
orders.ORD_CustFirstName,
orders.ORD_CustLastName,
orderstatuses.ORDSTATUS_Name,
paymentmethods.PAYMETH_Name,
shippingoptions.SHIPOPT_Name
ORDER BY
orders.ORD_ID
One simple thing you should consider is whether you really need to use left joins or you would be satisfied using inner joins for some of the joins. the new query would not be the same as the original query, so you would need to think carefully about what you really want back. If your foreign key relationships are indexed correctly, this could help substantially, especially between ORDERS and ORDERITEMS, because I would imagine these are your largest tables. The following post has a good explanation: INNER JOIN vs LEFT JOIN performance in SQL Server. There are lots of other things that can be done, but you will need to post the query plan so people can dive deeper.
It looks like just adding the index was all that was needed.
create index orderitems_ORD_ID_index on orderitems(ORD_ID);
I have problem with my query because of joining a lot of table. So I would like to find another ways beside this query but the result it the same. My code is bellow :
SELECT
tblReturn.CountryID,
tblReturn.ShopLocationId,
tblReturn.ReturnID,
tblVoucherDetail.VoucherDetailID,
tblVoucherDetail.VoucherNo,
tblVoucherDetail.BarcodeVoucher,
tblReturn.DateTimeStamp AS DateTimeReturn,
tblClient.ClientNoString,
tblSaleDetail.BarCode,
tblReturnType.Description,
tblReturn.Reason,
tblSale.DateTimeStamp AS DateTimeSale,tblReturn.Status
FROM
(
tblSale
INNER JOIN
(
(
(
tblReturn
INNER JOIN
(
tblVoucherDetail
INNER JOIN
tblVoucher ON tblVoucherDetail.VoucherID = tblVoucher.VoucherID
) ON tblReturn.ReturnID = tblVoucher.ReturnID
)
INNER JOIN
tblClient
ON
tblVoucherDetail.ClientNo = tblClient.ClientNo
)
INNER JOIN
tblSaleDetail
ON
tblReturn.SaleDetailIDOrigin = tblSaleDetail.SaleDetailID)
ON
(tblSale.SaleID = tblSaleDetail.SaleID)
AND
(tblSale.ShopLocationID = tblSaleDetail.ShopLocationID))
INNER JOIN
tblReturnType
ON
tblReturn.ReturnTypeID = tblReturnType.ReturnTypeID
WHERE
tblReturn.CountryID = 7
AND
tblReturn.ShopLocationID = 4
ORDER BY
tblVoucherDetail.VoucherDetailID DESC
How can I adjust it?
Use explain and indexes. http://dev.mysql.com/doc/refman/5.0/en/explain.html. Using indexes will enable the database to optimize the search
While optimizing your query is good (indexes are your friend), there is another approach you might consider with this many joins. "Denormalize" your database and create a table that has exactly the data you want. This involves updating your data both in the original table and in the new "report" table you create. There are obvious disadvantages to this -- (1) more space used, (2) you have to either write code to keep your data in sync, or you have to rebuild your "report" table on a periodic basis, (3) subtle bugs can happen if you data does get out of sync.
However, sometimes denormalizing is the simplest and best solution to nasty join performance problems.
I have a MySql Table with the following schema.
table_products - "product_id", product_name, product_description, product_image_path, brand_id
table_product_varient - "product_id", "varient_id", product_mrp, product_sellprice, product_imageurl
table_varients - "varient_id", varient_name
table_product_categories - "product_id", "category_id"
and this is the Mysql select query i am using to fetch the data for the category user provided.
select * from table_products, table_product_varients, table_varients, table_product_categories where table_product_categories.category_id = '$cate_id' && table_product_categories.product_id = table_products.product_id && table_products.product_id = table_product_varients.product_id && table_varients.varient_id = table_product_varients.varient_id
The problem is that, as table contains lot of products, and each product contains lot of varients, it is taking too much time to fetch the data. And i doubt, as data will grow, the time will increase to fetch the items. Is there any optimized way to achieve the same.
Your help will be highly appreciated.
Devesh
the query below would be a start, or something similar
SELECT
*
FROM
table_products P
INNER JOIN
table_product_categories PC
ON
PC.product_id = P.product_id
INNER JOIN
table_product_varients PV
ON
P.product_id = PV.product_id
INNER JOIN
table_varients V
ON
V.varient_id = PV.varient_id
where
table_product_categories.category_id = '$cate_id'
and as suggested do you really need to return * as this does mean selecting all columns from all tables within the query, which as we know from the joins themselves there a duplicates.
you should use indexing on tables for faster queries, set relationships between the joining tables this will also ensure referential integrity.
Hope this makes sense and helps :)
You can use the EXPLAIN command to see whats happening in the server. Then you can optimize the request by creating indexes.
Some links:
Some slides about tuning
MYSQL manual: 8.2.1. Optimizing SELECT Statements
yes you are correct, the query you are using above is not efficient:
you can get the same result as above by using ON clause instead of where clause.
the difference between them is, where clause gets all the rows and then filters out based on condidition specified.
Where as in case of ON Clause, the join haappens only on the rows which have met the condidtion specified in the ON clause
so..make your query as below:
So make use of joins instead of using where clause..
Hope this helps..
<?
include 'database.php';
$user1 = mysql_query("SELECT id,username FROM `users` ORDER BY `id` ASC");
while($user = mysql_fetch_object($user1)) {
mysql_query("UPDATE `pokemon` SET `user`=$user->id WHERE `owner`='$user->username'");
}
?>
Basically, I have over 300,000 users in my game, and there are millions of "Pokemon".
I was thinking of using an integer for the foreign key rather than a string, and so I have created this small little script to do that for me.
Unfortunately, it has only seemed to update 1000 users in the past hour, so therefore it would take me 300 hours for the whole thing to be completed. Is there a way I can make this script more efficient?
user is the new unique identifier, while owner is the old unique identifier (foreign key).
Is there an alternative solution to my method that would require less than 3-4 hours of time? I'm sure there must be some nice little SQL query I can just execute via phpMyAdmin rather than using this code.
Thanks for all the help, it really is appreciated and I will surely return the favour whenever possible.
Edit: Thanks for teaching me this new technique, I'll try it out and update my thread.
I think an UPDATE query with an INNER JOIN would be faster than a loop
UPDATE `pokemon` a
INNER JOIN `users` b
ON a.`owner` = b.`username`
SET a.`user`= b.`id`
You can JOIN the tables and then do the update in a single sql query:
UPDATE pokemon
LEFT JOIN users
ON pokemon.owner = users.username
SET pokemon.user = users.id
I am working on extracting and displaying data from a Wordpress DB to a mobile app for a customer and I am having a little trouble refining this query to be most efficient.
In wordpress, there are three tables that link the data I need to access
1. wp_posts - in this table there is the main post title, it's published status and the post type.
2. wp_postmeta - this table has all supplemental info related to the post id in the above table.
3. wp_p2p - this table has links to all the parent-child posts and their relationship.
Because of the volume of data in these tables, the query I currently have takes about 13 seconds to run, could you please take a look at this sqlfiddle and let me know what I could look at to improve it? The query in it's current form is not the end result, but improving it will improve my end result. I also need to add a search field on the "name" in the wp_postmeta table.
http://sqlfiddle.com/#!2/0e9e0/1
Any direction is appreciated, thank you!
If I understand correctly, you're looking for only child posts, in which case, the query below should be much faster:
SELECT wp_posts.id, post_title, post_status, post_type
FROM wp_posts
JOIN wp_postmeta ON (wp_posts.id = wp_postmeta.post_id)
LEFT JOIN wp_p2p ON (wp_posts.id = wp_p2p.p2p_from)
WHERE `post_status`='publish' AND `post_type`='merchant'
AND wp_p2p.p2p_from IS NULL
GROUP BY wp_posts.id
This query will be optimized to find where a match doesn't exist in the p2p table so that part will be much faster than how you're currently doing it. It looks like you can also remove the JOIN on wp_postmeta since you don't use it at all. Removing that JOIN would also make the GROUP BY redundant and removing it could help the performance a little. Removing the GROUP BY would also be a good practice since strictly you can't select non-aggregate fields that aren't in the GROUP BY clause, but MySQL provides for this functionality so the query will still work either way.
To begin with, you should join tables using INNER or OUTER JOIN syntax. So:
FROM wp_posts INNER JOIN wp_postmeta ON wp_posts.id = wp_postmeta.post_id
or perhaps you want an OUTER JOIN here?
Can you explain why you're doing a GROUP BY on wp_posts.id. Does this column not have unique values?