Как уменьшить время выполнения sql-запроса в моем приложении rails? - PullRequest
0 голосов
/ 07 января 2012

У меня есть запрос как

select i.shipping_charges, i.shipping_carrier, i.shipping_method, 
       i.tracking_number, i.origin_zip_code, i.origin_city, 
       i.origin_country, i.weight_value, i.weight_unit, 
       i.delivery_date, i.shipping_date, i.shipping_description, 
       i.delivery_zip_code, i.delivery_street_add, i.item_id, 
       i.start_at, i.end_at, i.id 
from (items it 
      left join item_shipping_details i on it.id = i.item_id) 
left join users u on u.id = it.alert_user_id 
where it.user_id=4 AND i.id in (35,602,1175,1176,1177,604,1178,1174,
                                1165,1179,930,1160,917,914,925,909,920,1147,910)  
                   AND (it.alert_user_id is null OR u.user_type in (2,3))  
                   AND (it.outbound != true OR it.outbound is null)

Для запуска требуется 8 мс в postgresql. Скажите, пожалуйста, другое альтернативное решение для этого?

Ответы [ 3 ]

2 голосов
/ 07 января 2012

Несколько вещей были странными или совершенно бессмысленными в вашем запросе.

  • Первичная таблица в списке FROM была items, но в основной таблице списка SELECT ее нет ни одного столбца. То, как вы это сделали, в лучшем случае добавило бы кучу строк только с NULL-значениями, что могло бы сбить с толку планировщика запросов. Вы не хотите ни того, ни другого.
    Я отменил заказ и сделал item_shipping_details основной стол. Это будет намного быстрее.

  • LEFT JOIN между items и item_shipping_details были противоречивыми, поскольку дополнительные предложения в любом случае требуют строки из обеих таблиц. Упрощенно до простого JOIN.
    Кроме того, порядок появления первых двух таблиц снова не имеет значения.

  • Убраны скобки вокруг первого JOIN, так как это бесполезно.

  • Упрощенно (it.outbound != true OR it.outbound is null) до it.outbound IS NOT TRUE

SELECT i.shipping_charges, i.shipping_carrier, i.shipping_method, 
       i.tracking_number, i.origin_zip_code, i.origin_city, 
       i.origin_country, i.weight_value, i.weight_unit, 
       i.delivery_date, i.shipping_date, i.shipping_description, 
       i.delivery_zip_code, i.delivery_street_add, i.item_id, 
       i.start_at, i.end_at, i.id 
FROM   item_shipping_details i
JOIN   items it ON it.id = i.item_id
LEFT   JOIN users u on u.id = it.alert_user_id 
WHERE  i.id IN (35,602,1175,1176,1177,604,1178,1174,1165,1179,
                930,1160,917,914,925,909,920,1147,910)
AND    it.user_id = 4
AND    it.outbound IS NOT TRUE
AND   (it.alert_user_id IS NULL OR u.user_type IN (2,3))

Должно значительно увеличить время выполнения ... производительность. :)

0 голосов
/ 07 января 2012

ЭТА ЧАСТЬ ВАШИХ ЗАПРОСОВ ВРЕМЕНИ

IN (35,602,1175,1176,1177,604,1178,1174,1165,1179,
            930,1160,917,914,925,909,920,1147,910)

ДА У «подзапросов» есть много способов:

  1. Использовать JOIN () и меньше INCLUDE () в ассоциации.
  2. Старайтесь избегать подзапросов и находите ([массив])
  3. Используйте кэш

Возможно, есть более лучшие варианты, которые вы можете найти ниже в rails doc http://guides.rubyonrails.org/active_record_querying.html

0 голосов
/ 07 января 2012

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

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