Подскажите друзья, почему тормозит мой самописный скрипт по выгрузке в xml файл? должно летать, но на выборке больше 100 заказов уже несколько минут выгружается, а если 1000 выгружать то ваще можно повеситься. PHP: ob_start(); require('includes/application_top.php'); require(DIR_WS_CLASSES . 'order.php'); $order_status = $HTTP_GET_VARS['orderstatus']; $lastorder = $HTTP_GET_VARS['lastorder']; $display_order_status = $order_status; if ($order_status == "") { $order_status = 1; } echo '<?xml version="1.0" encoding="windows-1251" ?> <Order_File>'; $query_status = "SELECT * FROM " . TABLE_ORDERS_STATUS . " where `orders_status_id` = $order_status AND language_id = $languages_id"; $status_result = tep_db_query($query_status); while ($row4 = tep_db_fetch_array($status_result)) { echo "("; $orders_status_name = $row4['orders_status_name']; echo $orders_status_name; echo ")"; } // FORM THAT LETS YOU SELECT WHICH ORDER STATUS TO DISPLAY ?> <?php if (!isset($lastorder)) { $lastorder=LASTORDER; } $query1 = "SELECT * FROM " . TABLE_ORDERS . " WHERE orders_status = $order_status and orders_id > $lastorder and orders_id < $lastorder+300 ORDER BY orders_id DESC"; $result = tep_db_query($query1); while ($row = tep_db_fetch_array($result)) { $customers_street_address = $row['customers_street_address']; $customers_city = $row['customers_city']; $customers_street2 = $row['customers_suburb']; if ($customers_street2 === '') { $customers_street2 = 'n/a'; } $customers_country = $row['customers_country']; $customers_email_address = $row['customers_email_address']; $customers_telephone = $row['customers_telephone']; $customers_id = $row['customers_id']; $customers_fax = $row['customers_fax']; $customers_postcode = $row['customers_postcode']; preg_match("/(.*?)([0-9].*)/", $customers_street_address, $customers_street_split); $delivery_company = $row['delivery_company']; $delivery_company = substr($delivery_company, 0, 30); $delivery_company = preg_replace('/&(?!\w{2,6};)/', '&', $delivery_company); if ($delivery_company === '') { $delivery_company = 'n/a'; } $delivery_postcode = $row['delivery_postcode']; $delivery_country = $row['delivery_country']; $date_purchased = $row['date_purchased']; $Day = substr($date_purchased, 8,2); $Month = substr($date_purchased, 5, 2); $Year = substr($date_purchased, 0, 4); $Time = substr($date_purchased, 11); $payment = $row['payment_method']; $ordernummer = $row['orders_id']; $delivery_name = $row{'delivery_name'}; $delivery_street_address = $row{'delivery_street_address'}; $delivery_city = $row{'delivery_city'}; $delivery_postcode = $row{'delivery_postcode'}; $customers_email_address = $row{'customers_email_address'}; $customers_telephone = $row{'customers_telephone'}; $query2 = "SELECT customers_firstname, customers_lastname FROM customers WHERE customers_id = $customers_id"; $result2 = tep_db_query($query2); $row_cust = tep_db_fetch_array($result2); $customers_firstname = $row_cust['customers_firstname']; $customers_lastname = $row_cust['customers_lastname']; $order = new order($ordernummer); $orders_history_query = tep_db_query("select orders_status_id, date_added, customer_notified, comments from " . TABLE_ORDERS_STATUS_HISTORY . " where orders_id = $ordernummer order by date_added"); if (tep_db_num_rows($orders_history_query)) { while ($orders_history = tep_db_fetch_array($orders_history_query)) { $comments = tep_db_output($orders_history['comments']); } } $payment = $row{'payment_method'}; $shiptaxt = $order->totals[1]['title']; $shiptax = $order->totals[1]['text']; $M_id = "CG"; echo " <Order> <Заказы> <Account_Ref>$M_id</Account_Ref> <Customer_ID>" . $M_id . "_$customers_id</Customer_ID> <Order_number>" . $M_id . "_$ordernummer</Order_number> <Date>$Day.$Month.$Year</Date> <Time>$Time</Time> <Delivery_Company_Name>$delivery_company</Delivery_Company_Name> <Delivery_Name>$delivery_name</Delivery_Name> <Street>$delivery_street_address</Street> <Street2>$delivery_suburb</Street2> <City>$delivery_city</City> <Postcode>$delivery_postcode</Postcode> <Payment>$payment</Payment> <Comments>$comments</Comments> <Shipping_Tax>$shiptax</Shipping_Tax> </Заказы> <Клиенты> <Account_Ref>$M_id</Account_Ref> <Customer_ID>" . $M_id . "_$customers_id</Customer_ID> <Customer_Name>$customers_firstname $customers_lastname</Customer_Name> <Street>$customers_street_address</Street> <Street2>$customers_street2</Street2> <City>$customers_city</City> <Postcode>$customers_postcode</Postcode> <Country>$customers_country</Country> <Email>$customers_email_address</Email> <Tel>$customers_telephone</Tel> <Tel2>$customers_fax</Tel2> </Клиенты>"; echo "<Заказано>"; // <Order_number>$ordernummer</Order_number> // <Customer_ID>$customers_id</Customer_ID> for ($i = 0, $n = sizeof($order->products); $i < $n; $i++) { $products_price = $order->products[$i]['price']; $quantity_price = $order->products[$i]['qty'] * $products_price; $products_model = preg_replace('/&(?!\w{2,6};)/', '&', $order->products[$i]['model']); $model_name = $order->products[$i]['name']; $model_name = preg_replace('/&(?!\w{2,6};)/', '&', $model_name); $product_qty = $order->products[$i]['qty']; echo " <Line> <Model_Code>$products_model</Model_Code> <Model_Name>$model_name</Model_Name> <Unit_Price>$products_price</Unit_Price> <Quantity>$product_qty</Quantity> <Quantity_Price>$quantity_price</Quantity_Price>"; //******************************************* //!!START MOD!!: Display Attribs //******************************************* //echo OL_MANU . ' ' . $mfg['manufacturers_name']."<br>"; //Doesn't work //echo OL_MODEL . ' ' . $order->products[$i]['model']."<br>"; //Doesn't work $j = 0; $colorset = 0; while ($products_options = $order->products[$i]['attributes'][$j]['option']) { $products_options = $order->products[$i]['attributes'][$j]['option']; $products_options_values = $order->products[$i]['attributes'][$j]['value']; if ($products_options == "Оптическая сила") { echo "<PWR>$products_options_values</PWR>"; } if ($products_options == "Радиус кривизны") { echo "<BC>$products_options_values</BC>"; } if ($products_options == "Цвет") { echo "<Color>$products_options_values</Color>"; $colorset = 1; } if ($products_options == "Цилиндр") { echo "<CYL>$products_options_values</CYL>"; } if ($products_options == "Ось") { echo "<AX>$products_options_values</AX>"; } if ($products_options == "Форма") { echo "<Color>$products_options_values</Color>"; $colorset = 1; } $j++; } If ($colorset != 1 and $j > 0) { echo "<Color>Прозрачный</Color>"; } echo "</Line>"; //******************************************* //!!END MOD!! //******************************************* ?> <?php } echo "</Заказано></Order>"; } echo "</Order_File>"; ob_end_flush(); ?> ну и далее идет уже разметка xml с тегами и переменными внутри них... Код (Text):
Оформи - это читать невозможно. Это раз. А второе http://xdebug.org/docs/profiler - лекарство именно для твоего случая.
no comments... А это что? Чтобы выяснить, что тормозит, ставьте таймеры (microtime) в основных функцональных блоках кода, так выясните, где конкретно появляются задержки. Из кода я ничего не понял: куда выгружаются xml-данные?
Kreker За прочтение мусора - тебе орден сутулого с закруткой на спине. А за это - штрафбат. Не учи плохому. Профилировщик сделает все то же самое, но лучше, полнее и нагляднее.
Это предложение включить мод телепата? Ок. Буфер переполняется. UPD: Ага, теперь вижу. Специфика в выводе. Тут дело даже не в конкретно этом коде, а дело в подходе. Попробуйте вывести миллион раз строку "АБС" и увидите тормоза.
Это не сильно важно. Но на первый взгляд у тебя получается очень много запросов в цикле. Лучше вытащить $ Код (Text): row = tep_db_fetch_array($result) за один раз все. Затем сформировать запрос сразу для всех выбранных $row Код (Text): $orders_history_query = tep_db_query("select orders_status_id, date_added, customer_notified, comments from " . TABLE_ORDERS_STATUS_HISTORY . " where orders_id = $ordernummer order by date_added"); И потом уже в цикле сформировать xml. Хотя лучше будет обернуть его в функцию и нужные переменные передать как аргументы. И таки спили мушку Т.е. сделай профайлинг, он тебе скажет все намного точнее чем мы на форуме. А делается очень легко.
просто зависает походу все таки не PHP а MYSQL когда делает select, тк в памяти именно mysql висит и жрет ее. может можно как-то аппаратно ускорить мускул? кеш побольше или еще что?
Я тебе подсказал. Выбрать все $row одним запросом в один общий массив. (mysql_fetch_assoc) Затем взять у них (в цикле у каждого) $ordernummer и записать в массив $ordernummerArray. Затем $orders_history_query выбрать тоже одним запросом [sql]' where orders_id IN (' . implode(',',$ordernummerArray) . ')'; [/sql] И последним циклом пробежаться по всем $row взять уже готовые данные из второго запроса и оформить в xml.
дык там же еще в конце таблица с товарами и хар-ками товаров поднимается на каждый заказ, я так думаю там тормозит то в основном... а первые 3 нельзя просто через left join объединить?
просто я вообще рекламой занимаюсь ))) а php постольку поскольку ковыряю... поэтому не особо в нем...
да оно работает вроде коекак, вот и морочусь ...это все для загрузки в 1с нужно, 1с ник есть, а PHP профи нету.
поменял вот большую часть echo на переменную, а потом ее целиком вывожу, но там явно в запросе дело, таблица где-то 100тыс строк, видимо как он по ней начинает выборку делать, так ему плохо и становится.
Найдите аутсорсера/фрилансера. Код сам по себе жутковатый. Большую часть присвоений - выкинуть. Вложенные циклы можно развернуть. Время работы с O(n^2) сократится до N*O(n)
База на 100к строк - это ерунда полная. У вас там для 1000 записей идет 1001 один запрос. Когда можно обойтись 2мя.
Поменял первый запрос на $query1 = "SELECT * FROM orders o left join customers c on c.customers_id=o.customers_id left join orders_status_history osh on osh.orders_id=o.orders_id WHERE o.orders_id > 1 and o.orders_id < 1000 and orders_status_id=1"; тоесть первые три запроса в один склеил... по microtime замерил скорость - почти вообще не повлияло зато помогла переиндексация таблиц, почти в 2 раза быстрее стало исполнятся + вынес из дополнительного модуля orders только нужные запросы, еще пару секунд на 100 заказов.. но и все... на глаз все равно тормозит поставил denwer на ramdisk еще, тож чутка быстрее вроде бы. В итоге вместо 40 секунд где-то 17... но это на 100, а на 5000 уже полчасика где-то.
Да, жесть.... ты ходил по этому линку? http://xdebug.org/docs/profiler Делал что я тебе говорил? Вот скажи мне пожалуйста. Ты читаешь что я пишу? Или мне можно заткнуться и не портить себе нервы? Ты в курсе какой запрос у тебя крутится тысячи раз?
ну я так понимаю что он один раз грузится как массив и потом уже из этого массива строчки считываются,?? или я не прав? $query1 = "SELECT * FROM " . TABLE_ORDERS . " WHERE orders_status = $order_status and orders_id > $lastorder and orders_id < $lastorder+300 ORDER BY orders_id DESC"; $result = tep_db_query($query1); while ($row = tep_db_fetch_array($result)) { Вот тут разве он повторяется???