Intereting Posts
Проверьте, является ли IP-адрес приватным как отправлять электронную почту с localhost с помощью php CodeIgniter php switch case statement для обработки диапазонов Как получить доступ к свойству класса родителя, если текущий класс был создан в родительском Почему dir_module НЕ загружается, хотя, очевидно, он загружается в папку httpd.conf и modules? Можно вставить данные в две разные таблицы в mysql одним вставным запросом php? Экспорт / импорт CSV с помощью PHPExcel Как разбить массив на основе определенного значения? Использование mysql для addlashes () Как написать простой прозрачный прокси PHP? Помощь в использовании JSON для API Как отформатировать миллисекунды в минутах: секунды: миллисекунды в PHP? Получение базовой информации из Instagram с использованием PHP Отправить файл через cURL из формы POST в PHP Объединение двух многомерных массивов с использованием ключа и добавление значений

Что быстрее / эффективнее – много маленьких запросов MySQL или одного большого массива PHP?

У меня есть веб-приложение на основе PHP / MySQL, которое поддерживает несколько языков с помощью таблицы MySQL «language_strings» с полями string_id, lang_id, lang_text. Затем я вызываю следующую функцию, когда мне нужно отобразить строку на выбранном языке …

public function get_lang_string($string_id,$lang_id) { $db=new Database(); $sql=sprintf("SELECT lang_string FROM language_strings WHERE lang_id IN (1, %s) AND string_id=%s ORDER BY lang_id DESC LIMIT 1", $db->escape($lang_id, "int"), $db->escape($string_id,"int")); $row=$db->query_first($sql); return $row['lang_string']; } 

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

Было бы быстрее загрузить все результаты таблицы language_strings для выбранного lang_id в массив PHP, а затем вызвать это из функции? Потенциально это было бы огромным массивом с большей частью избыточным, но, очевидно, это был бы один запрос к базе данных за pageload вместо лотов.

Может ли кто-нибудь предложить другой более эффективный способ сделать это?

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

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

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

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

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

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

Согласитесь с тем, что все говорят здесь. Все дело в цифрах.

Некоторые дополнительные советы:

  1. Попробуйте создать единый массив памяти, который имеет минимальный требуемый уровень. Это означает устранение большинства очевидных увольнений.

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

  3. Просто играйте с цифрами. Попробуйте использовать отдельные запросы (это самый простой подход) и подчеркните свой PHP-скрипт (например, вызывайте его сотни раз из командной строки). Измерьте, сколько времени это занимает, и посмотрите, насколько велика потеря производительности на самом деле. Говоря из моего личного опыта, я обычно кэширую все в памяти, а затем в один прекрасный день, когда данные становятся слишком большими, у меня заканчивается память. Затем я разбил все, чтобы отделить запросы, чтобы сохранить память, и увидеть, что влияние производительности было не так уж плохо в первую очередь 🙂

Хорошо. Я сделал некоторые бенчмаркинга и с удивлением обнаружил, что помещение вещей в массив, а не использование индивидуальных запросов, было в среднем 10-15% SLOWER.

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

С индивидуальными запросами я получаю только то, что мне нужно, и поскольку запросы настолько просты, что я лучше всего придерживаюсь этого метода.

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

Я нахожусь с Fluffeh на этом: рассмотрите другие варианты в вашем распоряжении (объединения, подзапросы, убедитесь, что ваши индексы отражают относительность данных, но не над индексом и тестом ). Скорее всего, в какой-то момент у вас получится массив, так что вот небольшой пример производительности, вопреки тому, что вы ожидаете,

 $all = $stmt->fetchAll(PDO::FETCH_ASSOC); 

меньше сравнивается с памятью:

 $all = array();//or $all = []; in php 5.4 while($row = $stmt->fetch(PDO::FETCH_ASSOC); { $all[] = $row['lang_string ']; } 

Более того: вы можете проверять избыточные данные и получать данные.

Мой ответ – сделать что-то среднее между ними. Извлеките все строки для lang_id, которые короче определенной длины (скажем, 100 символов). Более короткие текстовые строки, скорее всего, будут использоваться в нескольких местах, чем более длинные. Загрузите записи в статическом ассоциативном массиве в get_lang_string (). Если элемент не найден, загрузите его с помощью запроса.

В настоящее время я нахожусь в точке моего site/application где мне пришлось поставить тормоза и очень внимательно следить за скоростью. Я думаю, что упомянутые упомянутые тесты скорости должны учитывать объем трафика на вашем сервере как важную переменную, которая будет влиять на результаты. Если вы помещаете данные в структуры данных javascript и обрабатываете их на клиентской машине, время обработки должно быть более регулярным. Если вы запрашиваете много данных через mysql через php (например), это ставит спрос на один компьютер / сервер, а не распространяется на него. По мере роста вашего трафика вам приходится делиться ресурсами сервера со многими пользователями, и я думаю, что именно здесь, когда JavaScript делает больше, это облегчит нагрузку на сервер. Вы также можете хранить данные на локальном компьютере через localstorage.setItem(); / localstorage.getItem(); localstorage.setItem(); / localstorage.getItem(); (у большинства браузеров около 5 мб места на домен). Если у вас есть данные в базе данных, которые не так часто меняются, вы можете сохранить их клиенту, а затем просто проверить на «запуск», если он все еще в дате / действителен.

Это мой первый комментарий, опубликованный после использования и использования учетной записи в течение 1 года, поэтому мне, возможно, потребуется тонкая настройка моего бессвязного звонка – просто озвучивая то, о чем я думаю в настоящее время.