Насколько опасен этот SQL-запрос? - PullRequest
0 голосов
/ 22 февраля 2010

Запрос:

UPDATE 
  node as n
    right join content_type_product as c 
    on n.nid = c.nid 

    right join uc_products as p 
    on p.nid = n.nid 

    set 
       c.field_product_price_eur_value = p.sell_price * 0.0961, 
       c.field_product_price_zar_value = p.sell_price * 1, 
       c.field_product_price_gbp_value = p.sell_price * 0.0844, 
       c.field_product_price_usd_value = p.sell_price * 0.1305, 
       n.changed = now() 
    where n.type = 'product'

Для тех, кто еще не понял, этот запрос обновляет все узлы на сайте Drupal, чтобы у всех была последняя валюта. Мой вопрос: насколько опасен этот запрос, если у вас есть:

  1. 500 узлов
  2. 50 000 узлов
  3. 1 000 000 узлов

ЕСЛИ эта команда выполняется каждый час?

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

На сайте, где это будет выполнено, будет несколько записей узлов, и этот запрос обновляет 2 строки для каждого 1 продукта. Поэтому я не уверен, насколько сильно это будет напрягать сервер, если у меня будет множество узлов.

Ответы [ 4 ]

10 голосов
/ 22 февраля 2010

Я бы посоветовал сравнить это в вашей тестовой среде (у вас есть тестовая среда, верно?), Чтобы приблизительно определить, какую нагрузку будет испытывать ваш сервер. Очень сложно догадаться, какое влияние это окажет, не зная больше о вашей среде.

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

2 голосов
/ 22 февраля 2010

Это, без сомнения, довольно здоровенный звонок.

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

Моя единственная рекомендация - установить какую-то фильтрацию, чтобы обновлять только «активные» продукты. То есть продукты, которые видны публике. Если продукт переходит с неактивного на активный, он должен получить соответствующую цену в это время.

1 голос
/ 22 февраля 2010
c.field_product_price_zar_value = p.sell_price * 1, 

Ну, эта часть - пустая трата ресурсов, цена * 1 = цена. На самом деле, поскольку вы обновляете каждый раз на определенную сумму, я не уверен, что запрос все равно делает то, что вам нужно. В общем, я бы никогда не подумал обновить все цены, которые у меня есть в расписании, если не произойдет изменение, требующее их изменения. В вашем запросе нет ничего, что указывало бы на то, что произошло какое-либо изменение, так что это может произойти независимо от того, изменилось ли значение валюты (и то, как оно написано, не изменит значения, даже если валюта не изменилась). ИЛИ я не вижу части вашего процесса?

1 голос
/ 22 февраля 2010

Это таблица InnoDB или MyISAM? Если MyISAM заблокирует полную таблицу для всего запроса, это заблокирует все операции чтения на значительное время.

Я думаю, что сам запрос в порядке, но проверьте его с помощью EXPLAIN, чтобы убедиться, что у вас есть правильные индексы.

Вы также можете рассмотреть возможность использования vid и обновить только последнюю версию ваших узлов.

...