Скорость вычислений в SQL-выражении - PullRequest
2 голосов
/ 22 июня 2011

У меня есть таблица базы данных (MySQL) с тремя полями: id, счет и процент.

Короче говоря, мне нужно выполнить расчет для каждой записи, которая выглядит следующим образом:

(Оценка * 10) / (1 - процент) = Значение

И затем мне нужно использовать это значение как в моем коде, так и в качестве поля ORDER BY.Написание SQL не моя проблема - я просто беспокоюсь об эффективности этого утверждения.Делает ли это вычисление в моем операторе SQL наиболее эффективным способом использования ресурсов, или мне лучше взять данные и затем выполнить математику с помощью PHP?

Если SQL - лучший способ сделать это, есть лиСоветы, которые я могу иметь в виду, чтобы максимально ускорить выполнение SQL-запросов?

Обновление 1: Просто чтобы прояснить некоторые вопросы, потому что многие ответы предполагают по-разному:И Счет, и Процент будут постоянно меняться.Фактически, почти каждый раз, когда пользователь взаимодействует с приложением, эти поля изменяются (кстати, эти поля фактически связаны с пользователем).

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

Ответы [ 5 ]

4 голосов
/ 22 июня 2011

Похоже, что это расчетное значение имеет внутреннее значение в вашей области бизнеса; если это так, я бы рассчитал его один раз (например, во время создания записи) и использовал бы его, как любое обычное поле. Это, безусловно, самый эффективный способ достижения того, чего вы хотите - дополнительные вычисления при вставке или обновлении оказывают минимальное влияние на производительность, и с этого момента вам не нужно беспокоиться о том, кто и где выполняет вычисления. Недостатком является то, что вам необходимо обновить логику «вставки» и «обновления» для выполнения этого вычисления. Мне обычно не нравятся триггеры - они могут быть источником непроницаемых ошибок - но это тот случай, когда я их рассмотрю (http://dev.mysql.com/doc/refman/5.0/en/triggers.html).

Если по какой-то причине вы не можете этого сделать, я бы предложил сделать это на сервере базы данных. Это должно быть довольно быстро, если вы не имеете дело с очень большим количеством записей; в этом случае «упорядочить по» будет реальной проблемой производительности. Конечно, проблема производительности будет гораздо большей, если вы выполните ту же логику на стороне PHP, но ваша база данных, как правило, является узким местом с точки зрения производительности, поэтому влияние будет больше. Если вы имеете дело с большим количеством записей, вам, возможно, придется просто укусить пулю и пойти с моим первым предложением.

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

Итак, после всего этого мой реальный совет сводится к:

  • сделать самое простое, что могло бы сработать
  • проверить, достаточно ли это быстро в пределах ограничений вашего Проект
  • если нет, то итеративный рефакторинг для более быстрого решения, повторное тестирование
  • Как только вы достигнете "достаточно хорошо", двигайтесь дальше.

На основе редактировать 1 :

Я думаю, что вы ответили на свой вопрос - возвращать (в конечном итоге) 2 миллиона строк в PHP, только чтобы найти 20 лучших записей (после расчета их «значения» по одной), будет невероятно медленно. Так что вычисление в PHP на самом деле не вариант.

Итак, вы будете рассчитывать его на сервере. Я бы порекомендовал создать представление (http://dev.mysql.com/doc/refman/5.0/en/create-view.html), в котором есть SQL для выполнения расчета; сравните производительность представления с записями 200, 200K и 2M и посмотрите, достаточно ли это быстро.

Если это не достаточно быстро для 2M пользователей / записей, вы всегда можете создать обычную таблицу с индексом в столбце «значение», и в вашем клиентском коде сравнительно мало изменений; Вы можете заполнить новую таблицу с помощью триггеров, и клиентский код может никогда не узнать, что произошло.

1 голос
/ 22 июня 2011

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

0 голосов
/ 22 июня 2011

Где вы делаете математику не должно быть слишком важным. Это та же самая фундаментальная операция в любом случае. Теперь, если MySQL работает на сервере, отличном от вашего PHP-кода, вам может быть важно, какой процессор выполняет вычисления. Вы можете пожелать, чтобы SQL-сервер выполнял больше «тяжелой работы», или вы можете оставить SQL-сервер, выполняющий «только SQL», и перенести математическую логику в PHP.

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

Однако, если они оба работают на одном физическом оборудовании, это, по-видимому, не имеет заметного различия с точки зрения использования процессора.

Один совет, который я хотел бы предложить, - это выполнить ORDER BY для необработанного значения (процентов), а не для вычисленного значения - таким образом MySQL может использовать индекс для столбца процентов - он не может использовать индексы для вычисляемых значений. значения.

0 голосов
/ 22 июня 2011

Если у вас растет число записей, ваш скрипт (и его память) достигнут своих пределов быстрее, чем mysql.Вы планируете получить все записи в любом случае?Mysql будет быстрее в целом.Я не понимаю, как вы будете использовать значение, рассчитанное в php в ORDER BY впоследствии.Если вы планируете сортировать по php, он станет еще медленнее, но все зависит от количества записей, с которыми вы имеете дело.

0 голосов
/ 22 июня 2011

Протестируйте и дайте нам знать результаты производительности. Я думаю, что это будет зависеть от объема данных в вашем наборе результатов. Для бита SQL просто убедитесь, что ваше предложение where имеет закрытый индекс.

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