как ускорить Mysql и PHP? - PullRequest
       51

как ускорить Mysql и PHP?

6 голосов
/ 16 сентября 2009

Я занимаюсь разработкой сценария в моей локальной сети с использованием PHP и mysql и имею дело с большими данными (около 2 миллионов записей для научных исследований)

некоторые запросы, которые мне нужно вызывать один раз в жизни (для анализа данных и подготовки некоторых данных); однако это занимает очень много времени, например: теперь мой скрипт анализирует некоторые данные более 4 часов

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

например, я только что понял, что "индексация" может быть полезна для ускорения запросов однако даже при индексировании некоторых столбцов мой скрипт все еще очень медленный

любая идея, как ускорить мой скрипт (на PHP и mysql)

Я использую XAMPP в качестве серверного пакета

Большое спасибо за помощь

С наилучшими пожеланиями

обновление 1:

часть моего медленного сценария, обработка которого занимает более 4 часов

$sql = "select * from urls";//10,000 record of cached HTML documents
$result = $DB->query($sql);
while($row = $DB->fetch_array($result)){
$url_id = $row["id"];
$content = $row["content"];

$dom = new DOMDocument();
@$dom->loadHTML($content);
$xpath = new DOMXPath($dom);
$row = $xpath->evaluate("/html/body//a");

for($i = 0; $i < $row->length; $i++) {
     // lots of the code here to deal with the HTML documents and some update and insert and select queries which query another table which has 1 million record
}

обновление 2:

У меня нет запросов "JOIN" или даже "IN"

это очень простые запросы

и не знаю! и я не знаю, как узнать, что вызывает медлительность?

это PHP или MYSQL?

Ответы [ 6 ]

12 голосов
/ 16 сентября 2009

Прежде всего, чтобы иметь возможность эффективно оптимизировать, нужно знать, на что уходит время:

  • PHP делает слишком много вычислений?
  • у вас слишком много запросов SQL?
  • у вас есть SQL-запросы, которые занимают слишком много времени?
    • если да, то какие?
  • где твой сценарий проводит время?

С этой информацией вы можете попытаться выяснить:

  • если вы можете уменьшить количество запросов SQL
    • например, если вы делаете один и тот же запрос снова и снова, вы, очевидно, теряете время
    • другая идея - «перегруппировать» запросы, если это возможно; например, используйте только один запрос для получения 10 строк вместо 10 запросов, которые все возвращают одну строку.
  • если вы можете оптимизировать запросы, которые занимают слишком много времени
    • либо с использованием индексов - те, которые являются полезными, обычно зависят от соединений и условий, которые вы используете
    • или переписать запросы, если они "плохие"
    • Об оптимизации операторов выбора вы можете взглянуть на: 7.2. Оптимизация SELECT и других операторов
  • если PHP делает слишком много вычислений, можете ли вы сделать меньше вычислений?
    • Может быть, не пересчитывать подобные вещи снова и снова?
    • Или использовать более эффективные запросы?
  • если PHP требует времени, а сервер SQL не перегружен, использование параллелизма (запуск нескольких вычислений одновременно) также может помочь ускорить весь процесс.

Тем не менее: это довольно специфический вопрос, и ответы, вероятно, будут также довольно конкретными - это означает, что может потребоваться больше информации, если вам нужен более общий ответ ...


Редактировать после ваших правок

Поскольку у вас есть только простые запросы, все может быть немного проще ... Может быть.

  • Прежде всего: вам нужно определить тип запросов, которые вы делаете.
    • Я предполагаю, что из всех ваших запросов вы можете определить некоторые "типы" запросов.
    • например: «select * from a where x = 12» и «select * from a where x = 14» относятся к одному и тому же типу: один и тот же выбор, одна и та же таблица, предложение же - только изменение значения
  • как только вы узнаете, какие запросы используются чаще всего, вам нужно проверить, оптимизированы ли они: использование EXPLAIN поможет
    • (при необходимости, я уверен, что некоторые люди смогут помочь вам понять его вывод, если вы предоставите его вместе со схемой вашей БД (таблицы + индексы))
    • При необходимости: создать правильные индексы - это своего рода сложная / специфическая часть ^^
    • также для этих запросов может оказаться полезным уменьшение количества запросов ...
  • когда вы закончите с часто используемыми запросами, пора идти с запросами, которые занимают слишком много времени; использование microtime из PHP поможет вам выяснить, какие из них


Перед этим, чтобы выяснить, работает ли PHP слишком много или это MySQL, можно просто использовать команду "top" в Linux или "менеджер процессов" (я не в Windows, и не используйте его на английском - настоящее имя может быть чем-то другим) .

Если PHP потребляет 100% ресурсов процессора, у вас есть виновник. Если MySQL съест весь процессор, у вас тоже есть виновник.

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


Я вижу из вашей части кода, что вы:

  • прохождение 10000 элементов один за другим - должно быть легко разделить их на 2 или более фрагментов
  • с использованием DOM и XPath, которые могут потреблять некоторый процессор на стороне PHP

Если у вас многоядерный ЦП, идея (которую я бы попробовал, если бы увидел, что PHP потребляет много ЦП) должна распараллелить.

Например, вы можете запустить одновременно два экземпляра PHP-скрипта:

  • тот, который будет иметь дело с первой половиной URL
    • SQL-запрос для этого будет выглядеть как "select * from urls where id < 5000"
  • и другой, который будет иметь дело со второй половиной URL
    • его запрос будет выглядеть как "select * from urls where id >= 5000"

Вы получите немного больше параллелизма в сети (вероятно, не проблема) и в базе данных (база данных знает, как работать с параллелизмом, и 2 сценария, использующих ее, обычно не будут слишком большими) , но вы сможете обрабатывать почти вдвое одинаковое количество документов одновременно.

Если у вас 4 процессора, разделите список URL-адресов на 4 (или даже больше; выясните методом проб и ошибок) части тоже подойдут.

2 голосов
/ 16 сентября 2009

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

Большинство научных веб-приложений (например, BLAST) имеют возможность экспортировать данные в виде текстового файла с разделителями, такого как CSV. Если это так, вы можете подумать о реструктуризации вашей таблицы URL, чтобы у вас был один столбец на поле данных в CSV. Тогда ваши запросы на обновление будут значительно быстрее, так как вы сможете выполнять их полностью в SQL вместо того, чтобы извлекать всю таблицу URL в PHP, получать доступ и извлекать одну или несколько других записей для каждой записи URL, а затем обновлять таблицу.


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

1 голос
/ 16 сентября 2009

Знать запросы и структуры таблиц было бы проще.

Если вы не можете выдать их, проверьте, есть ли у вас оператор IN. MySQL имеет тенденцию слишком сильно замедляться. Также попробуйте запустить

EXPLAIN yourquery;

и посмотрите, как это выполняется. Иногда сортировка занимает слишком много времени. Старайтесь избегать сортировки по неиндексированным столбцам.

0 голосов
/ 16 сентября 2009

Прежде чем вы сможете оптимизировать, вам необходимо выяснить, где находится узкое место. Можете ли вы запустить сценарий для меньшего набора данных для целей тестирования?

В этом случае вы должны установить такой тест, а затем профилировать код. Вы можете использовать специальный профилировщик, такой как Xdebug , или если вам кажется слишком сложным в настройке (на самом деле это не сложно, но кажется, что вы уже немного разбираетесь) чувствовать себя более комфортно с ручным подходом. Это означает запуск таймера перед частями вашего кода и его остановку после, а затем распечатывание результата. Затем вы можете определить, какая часть медленнее.

Как только вы это получите, мы можем дать более конкретные ответы, или, возможно, вам будет очевидно, что делать.

0 голосов
/ 16 сентября 2009

Если вы не используете индексы, это может быть основной проблемой. Есть еще много полезных советов по оптимизации. Лучше будет показать твой самый медленный запрос. Невозможно помочь без каких-либо входных данных. Индексы и правильные объединения могут значительно ускорить это.

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

2 миллиона записей не много.

0 голосов
/ 16 сентября 2009

внутренние объединения выполняются быстрее, чем левые или правые соединения

Всегда ускорял выполнение моих запросов после, особенно задумываясь о соединениях.

загляните в конфигурацию mysql для настроек, которые вы можете отключить и т.д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...