Note that there are some explanatory texts on larger screens.

plurals
  1. POMassive MySQL update best approach?
    primarykey
    data
    text
    <p>I need to update the stock levels in my MySQL database 3 times a day from a CSV file.</p> <p>The CSV has over 27,000 products in there to be update and as you can imagine it takes a little while.</p> <p>I currently have a php script that runs the following:</p> <pre><code>select * from products where product_code = "xxxxxxx"; if num_rows &gt; 0 if new_stock_level = 0 UPDATE products SET `stock` = 0, `price` = 9.99 where product_code = "xxxxxxx"; else UPDATE products SET `stock` = 50, `price` = 9.99, `stock_date` = now() where product_code = "xxxxxxx"; </code></pre> <p>This is all well and good if you are updating &lt; 50 items but not 27,000!</p> <p>What would be the best way to do an update of this scale?</p> <p>I have been doing some reasearch and from what i can see mysqli prepared statments seem to be where i should be heading.</p> <p>After trying some of the bits mentioned below and what i have read online i have had the follwoing results with a batch of 250 updates.</p> <p>Changing from InnoDB to MyISAM on average increased the number of ubdate per sec from 7 to 27 which is a massive increase to start with.</p> <p>Prepareing the statment with case 9-10 sec</p> <pre><code>## Prepare the statment. $stmt = $mysqli-&gt;prepare("UPDATE products SET stock = case ? when 0 then 0 else ? end, price = ?, stock_date = case ? when 0 then stock_date else now() end WHERE product_code = ?"); $stmt-&gt;bind_param('dddds', $stock, $stock, $price, $stock, $prod); $stmt-&gt;execute(); </code></pre> <p>Non Prepared statment 9-10 sec</p> <pre><code>$sql = "UPDATE products SET stock = case " . $stock . " when 0 then 0 else " . $stock . " end, price = " . $price . ", stock_date = case " . $stock . " when 0 then stock_date else now() end WHERE product_code = \"" . $prod . "\";\n"; $mysqli-&gt;query($sql); </code></pre> <p>grouping statments in 50's and excuting with multi_query 9-10 sec</p> <pre><code>$mysqli-&gt;multi_query($sql); </code></pre> <p>Non prepared with 2 seperate querys depending if im updating the stock date or not. 8-9 Sec</p> <pre><code>if($stock &gt; 0) { $sql = "UPDATE products SET stock = " . $stock . ", price = " . $price . ", stock_date = now() WHERE product_code = \"" . $prod . "\";\n"; } else { $sql = "UPDATE products SET stock = " . $stock . ", price = " . $price . " WHERE product_code = \"" . $prod . "\";\n"; } $mysqli-&gt;query($sql); </code></pre> <p>prepared version of the same 8-9 sec</p> <pre><code>## Prepare statments $stmt1 = $mysqli-&gt;prepare("UPDATE products SET stock = ?, price = ?, stock_date = now() WHERE product_code = ?;"); $stmt1-&gt;bind_param('dds',$stock, $price, $prod); $stmt2 = $mysqli-&gt;prepare("UPDATE products SET stock = ?, price = ? WHERE product_code = ?;"); $stmt2-&gt;bind_param('dds', $stock, $price, $prod); if($stock &gt; 0) { $stmt1-&gt;execute(); } else { $stmt2-&gt;execute(); } </code></pre> <p>I aslo tried addeding an additional processor to the VPS and it made it about 4 querys a secound faster.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload