2012-02-20 3 views
0

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

Я пытаюсь использовать PHP для представления этих данных в определенном формате с помощью функции эха и размещения переменных с помощью {$ variable}.

Кроме того, данные являются иерархическими, поэтому я использовал команду соединения, чтобы включить несколько столбцов, а итоговая таблица, вероятно, составляла около 15 столбцов.

Я запустил файл php в Google Chrome, и он работал около 1 часа на довольно приличной машине core2duo.

Но результирующий набор остановился примерно на 18 тыс. Записей - кстати, я не поставил никаких ограничений на запрос.

Самая важная часть моего вопроса - как запустить этот файл, чтобы получить все результаты? Я не хочу сидеть там и устанавливать смещение снова и снова, если есть другой способ, я был бы очень благодарен.

Вторично - и я знаю, что вам, вероятно, нужна дополнительная информация, просто не уверен, что - могу ли я сделать процесс быстрее? Я планирую перезапустить его на более качественной машине, но есть ли другие способы?

Благодаря

Обновление:

<?php 
    include ('includes/functions.php'); 
    $connection=connectdb(); 

    $result=runquery(' 
    SELECT taxonomic_rank.rank as shortrank, scientific_name_element.name_element as shortname, sne.name_element as pname, tr.rank as prank 
    FROM taxon_name_element 
    LEFT JOIN scientific_name_element ON taxon_name_element.scientific_name_element_id = scientific_name_element.id 
    LEFT JOIN taxon ON taxon_name_element.taxon_id = taxon.id 
    LEFT JOIN taxonomic_rank ON taxonomic_rank.id = taxon.taxonomic_rank_id 
    LEFT JOIN taxon_name_element AS tne ON taxon_name_element.parent_id = tne.taxon_id 
    LEFT JOIN scientific_name_element AS sne ON sne.id = tne.scientific_name_element_id 
    LEFT JOIN taxon AS tax ON tax.id = tne.taxon_id 
    LEFT JOIN taxonomic_rank AS tr ON tr.id = tax.taxonomic_rank_id'); 
set_time_limit(0); 
ini_set('max_execution_time',0); 
    while($taxon_name_element = mysql_fetch_array($result)){ 
     if ($taxon_name_element['shortrank'] == 'species'){ 
      $subitem = $taxon_name_element['pname']."_".$taxon_name_element['shortname'];} 

     else{$subitem = $taxon_name_element['shortrank']."_".$taxon_name_element['shortname'];} 
     $parentitem = $taxon_name_element['prank']."_".$taxon_name_element['pname']; 
     echo 
"\n<!-- http://invertnet.ill/med#{$subitem}\" -->\n 
<owl:Class rdf:about=\"http://invertnet.ill/med#{$subitem}\"> 
    <rdfs:label xml:lang=\"en\">{$subitem}</rdfs:label> 
    <rdfs:subClassOf rdf:resource=\"http://invertnet.ill/med#{$parentitem}\"/> 
</owl:Class>\n\n";} 
echo "<br>".count($taxon_name_element)." number of stuff"; 
?> 
+0

Добавьте некоторые индексы на столбцы, к которым вы присоединяетесь, и пропустите PHP. Просто используйте терминал и выведите результаты в файл. – thetaiko

+8

Какой ответ вы ожидаете получить? Нет никаких подробностей. Поэтому единственное, что мы можем сделать, это просто молиться за вас. – zerkms

+0

thetaiko: спасибо, я сделаю это; zerkms: ваши молитвы приветствуются! знак равно Я не был уверен, какие детали релевантны: sql-запрос, php-код или я должен просто предоставить все? спасибо – SimaPro

ответ

1

Чтение ниже линии, это, кажется, не будет медленным проблема запроса.

«Я запустил php-файл в Google Chrome, и он работал около 1 часа на довольно приличной машине core2duo. Но результирующий набор остановился примерно на 18 тысячах записей - я не ограничил запрос по путь "

Браузер не самый лучший способ выбросить 10 миллионов записей, а не Chrome по крайней мере :-). Мое предположение состоит в том, что вы помещаете некоторые фрагменты в свой PHP-файл, чтобы вам не приходилось вручную устанавливать смещение вручную. Поместите простую предыдущую ссылку, показывающую 10000 записей на странице.

Если это не совсем необходимо для запуска в браузере, другим способом может быть запись всего вывода в текстовый файл.

Некоторые примечания по запросу: любая конкретная причина добавления LEFT JOIN дважды для каждой таблицы? Кажется, что это связано с taxon_name_element.parent_id, но поскольку я не уверен в требовании и схеме таблицы, не могу прокомментировать это. Но если запрос работает слишком медленно, подумайте над его оптимизацией.

EDIT 1 - Я попытался немного поработать над вашим запросом. И так как вы хотите как имя элемента, так и его родительское имя, я думаю, что это можно сделать в более простом запросе без совместного подключения к тем же таблицам дважды. Однако потребуется кодирование некоторой дополнительной логики.

Несколько замечаний, которые я узнал из запроса:

  1. элемента и его родитель имя оба приходят из тех же таблиц taxon_name_element
  2. есть еще один столбец «ранг» и это также исходят из та же таблица taxonomic_rank как для элемента и его родителя
  3. Из этого специфического присоединиться taxon_name_element.parent_id = tne.taxon_id, я узнал, что оба элемента и его родителя находятся в одной и той же таблицы `taxon_name_element»

Теперь давайте посмотрим простой запрос:

SELECT `tr`.`rank` AS `shortrank`, `sne`.`name_element` AS `shortname`, `tne`.`parent_id`, `tne`.`taxon_id` 
FROM `taxon_name_element` `tne` 
LEFT JOIN `scientific_name_element` `sne` ON `tne`.`scientific_name_element_id` = `sne`.`id` 
LEFT JOIN `taxon` `tax` ON `tne`.`taxon_id` = `tax`.`id` 
LEFT JOIN `taxonomic_rank` `tr` ON `tr`.`id` = `tax`.`taxonomic_rank_id`; 

результирующего теперь будет содержать как taxon_id и parent_id. Таким образом, идея состоит в том, чтобы хранить все результаты в массиве так, чтобы KEY был установлен в parent_id. Нравится:

$arrOutput = $arrParent = Array(); 
while ($row = mysql_fetch_array($result) { 
    $arr = Array(
     'shortrank' => $row['shortrank'], 
     'shortname' => $row['shortname'], 
     'taxonid' => $row['taxon_id'], 
     'parentid' => $row['parent_id'] 
     ); 
    $arrOutput[] = $arr; 
    if (!empty($row['parent_id'])) { 
     $arrParent[$row['parent_id']] = $arr; 
    } 
} 
// $arrOutput is now the final array with all the results and you can loop through it like you do in your original code. When looping, the parent can directly be accessed using parent_id as the associative key. 
foreach ($arrOutput as $arr) { 
    $elementName = $arr['shortname']; 
    $elementRank = $arr['shortrank']; 
    $parentName = $arrParent[$arr['parentid']]['shortname']; 
    $parentRank = $arrParent[$arr['parentid']]['shortrank']; 
} 

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

ВНИМАНИЕ: приведенный выше код не проверен, и я надеюсь, что он работает. Могут потребоваться незначительные изменения или исправления ;-)

+0

Abhay, спасибо ... Мне нужно будет вывести его в новый файл (мне нужно будет узнать, как это сделать). Причина, по которой я дважды вызывал несколько разделов, заключается в том, что я могу получить не только имя элемента, для которого я искал, но и имя родителя. Это связано с тем, что мне нужно отображать как дочерний, так и родительский для каждой записи. Благодаря! – SimaPro

+0

С благодарностью @SimaPro, не стесняйтесь спрашивать, есть ли у вас какие-либо вопросы. Кстати, я просто добавил несколько комментариев к моему ответу. Надеюсь, они помогут! – Abhay

 Смежные вопросы

  • Нет связанных вопросов^_^