php скрипт вызывает 100% процессоров по mysql

У меня есть PHP-скрипт, который создает CSV-файл.

Когда я запускаю его, сервер всегда загружен на 100%, и я не могу зайти на сайт в течение 4/5 минут.

Как я могу ограничить использование процессора для этого скрипта?

В скрипте есть mysql SELECT с около 30000 строк результата и некоторыми strip_tags.

заранее спасибо

Небольшая часть кода:

       $listing_sql = "SELECT
p.products_id,
p.products_image,
p.manufacturers_id,
p.products_details_original_supplier_code,
p.products_details_original_prod_code,
p.products_weight,
p.products_tax_class_id AS tax_id,
p.products_quantity_local AS availability,
pd.products_name,
g.customers_group_price,
pd.products_description,
p2c.categories_id,
c.parent_id,
c.categories_id,
cd.categories_name,
m.manufacturers_id,
g.customers_group_price,
g.products_id,
IF(p.manufacturers_id = 0, NULL, m.manufacturers_name) AS marca,
IF(s.status, s.specials_new_products_price, NULL) AS specials_new_products_price,
IF(s.status, s.specials_new_products_price, g.customers_group_price) AS final_price,
IF(p.products_model = NULL, -1, p.products_model) as codprod
FROM
".TABLE_PRODUCTS." p
LEFT JOIN ".TABLE_SPECIALS." s ON p.products_id = s.products_id
LEFT JOIN ".TABLE_MANUFACTURERS." m ON p.manufacturers_id = m.manufacturers_id
LEFT JOIN ".TABLE_PRODUCTS_GROUPS." g ON p.products_id = g.products_id AND g.customers_group_id = 3,
".TABLE_PRODUCTS_DESCRIPTION." pd,
".TABLE_PRODUCTS_TO_CATEGORIES." p2c,
".TABLE_CATEGORIES." c,
".TABLE_CATEGORIES_DESCRIPTION." cd

WHERE
p2c.categories_id = c.categories_id AND
c.categories_id = cd.categories_id AND
p.products_id = p2c.products_id AND
pd.products_id = p2c.products_id AND
pd.language_id = '$language_id' AND
cd.language_id = '$language_id'
ORDER BY final_price DESC
";

$filestring.=$row["products_id"]."|".$row["products_name"]."|".$site_url."/images/".$row["products_image"]."|".$site_url."/product_info.php?products_id=".$row["products_id"]."|".$cat_list."|".$final_price."|".$descrizione1."|".$row["marca"]."|" . $row["availability"] ."|" . $shippingprice2 ."|" . $row["codprod"]."|".$row["products_details_original_supplier_code"]."|".$row["products_details_original_prod_code"]."<endrecord>\r\n";$rescount += 1;// $rescount++;
}
//      echo $filestring;

$filename = $file."name_file";
file_put_contents("./files/$filename.csv", "$filestring");
exit;

.

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;

--
-- Database: `namedb`
--

-- --------------------------------------------------------

--
-- Struttura della tabella `oscpro_categories`
--

CREATE TABLE IF NOT EXISTS `oscpro_categories` (
`on_header` int(1) default '0',
`categories_id` int(11) NOT NULL auto_increment,
`categories_image` varchar(255) default NULL,
`parent_id` int(11) NOT NULL default '0',
`sort_order` int(3) default NULL,
`date_added` datetime default NULL,
`last_modified` datetime default NULL,
`categories_import_module_codes` varchar(255) default NULL,
`categories_status` tinyint(1) unsigned NOT NULL default '1',
`categories_allowed_customers_gid` int(11) default '0',
`categories_image_top` varchar(255) default NULL,
`categories_oscproie_module_code` varchar(255) default 'OSCPROIE',
PRIMARY KEY  (`categories_id`),
KEY `idx_categories_parent_id` (`parent_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1748 ;

-- --------------------------------------------------------

--
-- Struttura della tabella `oscpro_categories_description`
--

CREATE TABLE IF NOT EXISTS `oscpro_categories_description` (
`categories_id` int(11) NOT NULL default '0',
`language_id` int(11) NOT NULL default '1',
`categories_name` varchar(255) default NULL,
`categories_description` text,
`categories_pages_descriptionmetatag` text,
`categories_pages_keywordsmetatag` varchar(255) default NULL,
`categories_pages_titletag` varchar(255) default NULL,
`categories_image_alttag` varchar(255) default NULL,
`categories_pages_htmlseocode` text,
PRIMARY KEY  (`categories_id`,`language_id`),
KEY `idx_categories_name` (`categories_name`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

-- --------------------------------------------------------

--
-- Struttura della tabella `oscpro_manufacturers`
--

CREATE TABLE IF NOT EXISTS `oscpro_manufacturers` (
`manufacturers_id` int(11) NOT NULL auto_increment,
`manufacturers_name` varchar(32) default NULL,
`manufacturers_image` varchar(64) default NULL,
`date_added` datetime default NULL,
`last_modified` datetime default NULL,
`manufacturers_import_module_codes` varchar(255) default NULL,
`manufacturers_oscproie_module_code` varchar(255) default 'OSCPROIE',
PRIMARY KEY  (`manufacturers_id`),
KEY `IDX_MANUFACTURERS_NAME` (`manufacturers_name`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=610 ;

-- --------------------------------------------------------

--
-- Struttura della tabella `oscpro_products`
--

CREATE TABLE IF NOT EXISTS `oscpro_products` (
`products_id` int(11) NOT NULL auto_increment,
`products_quantity` int(11) NOT NULL default '0',
`products_details_original_supplier_code` varchar(64) default NULL,
`products_image_hot_linking_big` varchar(255) default NULL,
`products_image_hot_linking_medium` varchar(255) default NULL,
`products_image_hot_linking_small` varchar(255) default NULL,
`products_image` varchar(255) default NULL,
`products_image_extra1` varchar(255) default NULL,
`products_image_extra2` varchar(255) default NULL,
`products_image_extra3` varchar(255) default NULL,
`products_image_extra4` varchar(255) default NULL,
`products_image_extra5` varchar(255) default NULL,
`products_image_extra6` varchar(255) default NULL,
`products_price` decimal(15,4) NOT NULL default '0.0000',
`products_date_added` datetime default NULL,
`products_last_modified` datetime default NULL,
`products_date_available` datetime default NULL,
`products_weight` decimal(15,3) NOT NULL default '0.000',
`products_status` tinyint(1) NOT NULL default '0',
`products_carrot` tinyint(1) default '0',
`products_tax_class_id` int(11) NOT NULL default '0',
`manufacturers_id` int(11) NOT NULL default '0',
`products_ordered` int(11) NOT NULL default '0',
`products_percentage` tinyint(1) NOT NULL default '1',
`products_details_original_prod_code` varchar(64) default NULL,
`products_model` varchar(64) default NULL,
`products_details_pages_numbers` int(12) default '0',
`products_details_isbn` varchar(255) default NULL,
`products_details_upc` varchar(10) default NULL,
`products_details_release_date` datetime default NULL,
`products_details_run_time` int(12) default NULL,
`products_import_module_codes` varchar(255) default NULL,
`products_details_outside_code` varchar(255) default NULL,
`products_image_hot_linking` tinyint(1) default NULL,
`products_to_rss` tinyint(4) NOT NULL default '1',
`products_master` int(11) NOT NULL default '0',
`products_master_status` tinyint(2) NOT NULL default '-1',
`products_master_type` tinyint(1) NOT NULL default '1',
`products_listing_status` tinyint(2) NOT NULL default '1',
`products_master_temp` varchar(255) default NULL,
`products_ship_price` varchar(255) default NULL,
`products_ship_flag` tinyint(1) default '0',
`products_quantity_local` int(11) default '0',
`products_quantity_remote` int(11) default '0',
`products_details_oscproie_code` varchar(255) default NULL,
`products_oscproie_module_code` varchar(255) default 'OSCPROIE',
`products_bundle` enum('no','yes') NOT NULL default 'no',
`sold_in_bundle_only` enum('no','yes') NOT NULL default 'no',
`icecatcode` varchar(64) NOT NULL default '',
`eancode` varchar(13) NOT NULL default '',
PRIMARY KEY  (`products_id`),
KEY `idx_products_date_added` (`products_date_added`),
KEY `idx_products_model` (`products_details_original_supplier_code`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=39294 ;

-- --------------------------------------------------------

--
-- Struttura della tabella `oscpro_products_description`
--

CREATE TABLE IF NOT EXISTS `oscpro_products_description` (
`products_id` int(11) NOT NULL auto_increment,
`language_id` int(11) NOT NULL default '1',
`products_name` varchar(255) NOT NULL,
`products_description` text,
`products_url` varchar(255) default NULL,
`products_url_title` varchar(255) default NULL,
`products_url_extra1` varchar(255) default NULL,
`products_url_extra1_title` varchar(255) default NULL,
`products_url_extra2` varchar(255) default NULL,
`products_url_extra2_title` varchar(255) default NULL,
`products_url_extra3` varchar(255) default NULL,
`products_url_extra3_title` varchar(255) default NULL,
`products_url_extra4` varchar(255) default NULL,
`products_url_extra4_title` varchar(255) default NULL,
`products_viewed` int(5) default '0',
`products_details_author` varchar(255) default NULL,
`products_details_label` varchar(255) default NULL,
`products_details_distributedby` varchar(255) default NULL,
`products_details_levels` varchar(255) default NULL,
`products_details_language` varchar(255) default NULL,
`products_details_format` varchar(255) default NULL,
`main_image_alt_tag` varchar(255) default NULL,
`products_details_generic3` varchar(255) default NULL,
`products_details_titletag` varchar(255) default NULL,
`products_details_keywordsmetatag` varchar(255) default NULL,
`products_details_descriptionmetatag` text,
`products_details_hot_linking` varchar(255) default NULL,
PRIMARY KEY  (`products_id`,`language_id`),
KEY `products_name` (`products_name`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=39294 ;

-- --------------------------------------------------------

--
-- Struttura della tabella `oscpro_products_groups`
--

CREATE TABLE IF NOT EXISTS `oscpro_products_groups` (
`customers_group_id` int(11) NOT NULL default '0',
`customers_group_price` decimal(15,4) NOT NULL default '0.0000',
`products_id` int(11) NOT NULL default '0',
`products_price` decimal(10,0) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

-- --------------------------------------------------------

--
-- Struttura della tabella `oscpro_products_to_categories`
--

CREATE TABLE IF NOT EXISTS `oscpro_products_to_categories` (
`products_id` int(11) NOT NULL default '0',
`categories_id` int(11) NOT NULL default '0',
PRIMARY KEY  (`products_id`,`categories_id`),
KEY `ptc_catidx` (`categories_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

-- --------------------------------------------------------

--
-- Struttura della tabella `oscpro_specials`
--

CREATE TABLE IF NOT EXISTS `oscpro_specials` (
`specials_id` int(11) NOT NULL auto_increment,
`products_id` int(11) NOT NULL default '0',
`specials_new_products_price` decimal(15,4) NOT NULL default '0.0000',
`specials_date_added` datetime default NULL,
`specials_last_modified` datetime default NULL,
`expires_date` datetime default NULL,
`date_status_change` datetime default NULL,
`status` int(1) NOT NULL default '1',
`customers_group_id` int(11) NOT NULL default '0',
PRIMARY KEY  (`specials_id`),
KEY `idx_specials_products_id` (`products_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=303 ;

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

-4

Решение

Некоторые начальные мысли по оптимизации:

p2c.categories_id = c.categories_id AND
c.categories_id = cd.categories_id AND
p.products_id = p2c.products_id AND
pd.products_id = p2c.products_id

Похоже, что это соединения в старом стиле. Так как они являются полными соединениями, я бы начал с переключения их на INNER JOIN типы. Я не знаю, принесет ли это выигрыш в производительности, но он сообщает базе данных, что это соединение, а не сравнение на основе общего равенства, и, таким образом, может быть в состоянии произвести оптимизацию на лету.

AND
pd.language_id = '$language_id' AND
cd.language_id = '$language_id'

Похоже, у вас нет индексов в этих столбцах, поэтому начните с них и снова измерьте производительность своего запроса.

Затем проверьте столбцы соединения и попробуйте добавить к ним индексы. Ведите точный журнал того, какие индексы вы добавляете: не просто создавайте индекс для всего, так как это может повредить INSERT производительность в другом месте. Я хотел бы добавить индекс, измерить изменение производительности, удалить его, добавить другой, измерить изменение производительности, а затем, возможно, попробовать два вместе и т. Д.

Не забудьте посмотреть на ваш план объяснения, чтобы увидеть, где находится узкое место.

Ваша версия MySQL также очень старая, вы можете ее обновить?


Кроме того, рассмотрите решение проблемы другим способом. Как я упоминал в комментариях, Apache блокируется во время выполнения этого длительного процесса; я предполагаю, что это является причиной того, что сайт не работает в то же время, и вообще не связан с загрузкой процессора. Сайт может работать медленнее для других пользователей, но не должен блокироваться полностью.

Таким образом, настройте cron для выполнения этого запроса и сохранения результатов за пределами вашего веб-процесса, и ваш сайт должен оставаться в рабочем состоянии, пока он работает. Попробуйте — это достаточно просто настроить!


Третье, что нужно попробовать: ваши таблицы — MyISAM, которые, как я считаю, блокируются на уровне таблицы, а не на уровне строки. Таким образом, скопируйте свои данные на тестовую машину и настройте свой сайт, и подтвердите, что пока ваш скрипт выполняется в этой неживой среде, он недоступен. Затем, преобразовать ваши таблицы в InnoDB, и посмотрим, не исчезнет ли проблема. InnoDB блокирует на уровне строк, и поэтому может разрешить доступ, даже когда другие строки заняты вашим долгосрочным запросом.

Другой способ подтвердить это может быть создание тривиального сценария PHP и таблицы MySQL, чтобы сценарий считывал / записывал в таблицу. Он все еще должен работать, когда ваш долгосрочный скрипт активен, и если он это делает, он покажет, что MySQL по-прежнему отвечает на запросы нормально, но что любые запросы с участием заблокированных столов придется ждать.

1

Другие решения

Других решений пока нет …