Как можно оптимизировать запрос
Есть таблица (уже 70млн записей)
Делаю селект, далее инсерт в другую таблицу и затем удаляю строку, которая перенесена в другую таблицу. Селект и Инсерт проходят моментально, а вот удаление весь процесс тормозит.
Можно как-то оптимизировать. 22 минуты уходит на перенос 60000 строк.
- 29 июня 2009, 02:42
- ava36
Ответы (8)
RSS(При выполнении команды SELECT у Вас не используется никаких условий, то есть база берёт первые попавшиеся строки - это работает быстрее некуда. При выполнении INSERT тоже тормозить особо не на чем - назначительные ресурсы могли бы тратиться на перестройку индексов, но у Вас они отсутствуют. А вот при выполнении DELETE база перебирает всю таблицу, чтобы выбрать нужные строки - на это и уходит время - если сделать индексы, всё быдет работать очень быстро).
Уверен, что добавление одного индекса для всех нужных полей решит Вашу проблему (70млн записей для MySQL - это не так уж много), но если всё-таки не решит, то воспользуйтесь советом kmike - сделайте дополнительное поле-флаг, только не забудьте создать индекс для этого поля. (К сожалению, структуру таблицы raw_a Вы так и не указали, поэтому можно только гадать - нет ли в этой таблице поля с уникальными id, если есть, то вместо дополнительного поля лучше использовать это).
lia
//config
$config[mysql_host] = "localhost";
$config[mysql_login] = "root";
$config[mysql_password] = "7e7b33d7";
$config[ulog_limit] = "10000";
$config[ulog_limit_s] = "5";
//ulog connect
echo "Загрузка базы ulog...";
flush();
$ulog_mysqlcon = mysqli_connect($config[mysql_host], $config[mysql_login], $config[mysql_password]);
mysqli_select_db($ulog_mysqlcon, "ulog");
echo "<font color='green'>выполнено</font><br>";
flush();
echo "Создание второго подключения для отгрузки...";
flush();
$mscon = mysqli_connect($config[mysql_host], $config[mysql_login], $config[mysql_password]) or die(mysqli_error());
mysqli_select_db($mscon, "ulog_2008");
echo "<font color='green'>выполнено</font><br>";
flush();
$all_time = 0;
//Выборка
for($i=0; $i<=$config[ulog_limit_s];$i++)
{
$var_time = time();
echo "<br>Выборка ".$config[ulog_limit]." записей...";
flush();
$ulog_mysql_query = mysqli_query($ulog_mysqlcon, "SELECT * FROM raw_a LIMIT ".$config[ulog_limit]."") or die(mysqli_error($ulog_mysqlcon));
$i_num = 0;
$ms_aff = 0;
$i_np = 0;
$i_percent = $config[ulog_limit]/100;
echo "<font color='green'>выполнено</font><br>";
flush();
echo "[";
while($ulog_mysql_array = mysqli_fetch_array($ulog_mysql_query))
{
$table = date("m_d_Y", $ulog_mysql_array[unix_secs]);
$mysql_add_tb = mysqli_query($mscon, "CREATE TABLE IF NOT EXISTS $table (
`id` int(15) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`unix_secs` int(11) unsigned NOT NULL default '0',
`unix_nsecs` int(11) unsigned NOT NULL default '0',
`sysuptime` int(11) unsigned NOT NULL default '0',
`exaddr` varchar(45) NOT NULL default '0',
`dflows` int(11) unsigned NOT NULL default '0',
`dpkts` int(11) unsigned NOT NULL default '0',
`doctets` int(11) unsigned NOT NULL default '0',
`first` int(11) unsigned NOT NULL default '0',
`last` int(11) unsigned NOT NULL default '0',
`engine_type` tinyint(3) unsigned NOT NULL default '0',
`engine_id` tinyint(3) unsigned NOT NULL default '0',
`srcaddr` varchar(45) NOT NULL default '0',
`dstaddr` varchar(45) NOT NULL default '0',
`nexthop` varchar(45) NOT NULL default '0',
`input` smallint(5) unsigned NOT NULL default '0',
`output` smallint(5) unsigned NOT NULL default '0',
`srcport` smallint(5) unsigned NOT NULL default '0',
`dstport` smallint(5) unsigned NOT NULL default '0',
`prot` tinyint(3) unsigned NOT NULL default '0',
`tos` tinyint(3) unsigned NOT NULL default '0',
`tcp_flags` tinyint(3) unsigned NOT NULL default '0',
`src_mask` tinyint(3) unsigned NOT NULL default '0',
`dst_mask` tinyint(3) unsigned NOT NULL default '0',
`counted` int(0) unsigned NOT NULL default '0'
) ENGINE=MyISAM") or die(mysqli_error($mscon));
$mysql_add_line = mysqli_query($mscon, "INSERT INTO $table
(id,
unix_secs,
unix_nsecs,
sysuptime,
exaddr,
dflows,
dpkts,
doctets,
first,
last,
engine_type,
engine_id,
srcaddr,
dstaddr,
nexthop,
input,
output,
srcport,
dstport,
prot,
tos,
tcp_flags,
src_mask,
dst_mask) VALUES
(NULL,
'$ulog_mysql_array[unix_secs]',
'$ulog_mysql_array[unix_nsecs]',
'$ulog_mysql_array[sysuptime]',
'$ulog_mysql_array[exaddr]',
'$ulog_mysql_array[dflows]',
'$ulog_mysql_array[dpkts]',
'$ulog_mysql_array[doctets]',
'$ulog_mysql_array[first]',
'$ulog_mysql_array[last]',
'$ulog_mysql_array[engine_type]',
'$ulog_mysql_array[engine_id]',
'$ulog_mysql_array[srcaddr]',
'$ulog_mysql_array[dstaddr]',
'$ulog_mysql_array[nexthop]',
'$ulog_mysql_array[input]',
'$ulog_mysql_array[output]',
'$ulog_mysql_array[srcport]',
'$ulog_mysql_array[dstport]',
'$ulog_mysql_array[prot]',
'$ulog_mysql_array[tos]',
'$ulog_mysql_array[tcp_flags]',
'$ulog_mysql_array[src_mask]',
'$ulog_mysql_array[dst_mask]')") or die(mysqli_error($mscon));
$mysql_delete_line = mysqli_query($ulog_mysqlcon, "DELETE FROM raw_a WHERE
unix_secs = '$ulog_mysql_array[unix_secs]' AND
unix_nsecs = '$ulog_mysql_array[unix_nsecs]' AND
sysuptime = '$ulog_mysql_array[sysuptime]' AND
exaddr = '$ulog_mysql_array[exaddr]' AND
dflows = '$ulog_mysql_array[dflows]' AND
doctets = '$ulog_mysql_array[doctets]' AND
srcaddr = '$ulog_mysql_array[srcaddr]' AND
dstaddr = '$ulog_mysql_array[dstaddr]' AND
srcport = '$ulog_mysql_array[srcport]' AND
dstport = '$ulog_mysql_array[dstport]' LIMIT 1");
$ms_aff = $ms_aff + mysqli_affected_rows($ulog_mysqlcon);
$i_num++;
if($i_num == $i_percent)
{
$i_num = 0;
echo ":";
$i_np ++;
flush();
}
if($i_np == "50")
{
echo "50%";
flush();
$i_np++;
}
if($i_np > "100")
{
echo "]";
flush();
}
}
$var_time_end = time();
$var_sec = $var_time_end-$var_time;
echo "<br>".$config[ulog_limit]."/".$ms_aff." записей обработано за ".$var_sec." секунд";
$all_time = $all_time+$var_sec;
}
echo "<br>Общее время: ".$all_time." секунд";
//data
?>
Написал весь скрипт.
eter-2008
eponyatnaya-lichnost
imax
что именно оптимизировать ?
получается не оптимизация а написание своего :)
piker01
еще вариант без delete каждый раз - в строке ставь какой-нить флаг, что она удалена (перенесена), а удалять потом все кучей, по расписанию.
imple
lena-ucky
atros-heleznyak
Только зарегистрированные и авторизованные пользователи могут отвечать.