ФорумРазработкаБазы данных → Как сократить запрос

Как сократить запрос

  • lowfuck

    Сообщения: 20 Репутация: N Группа: Кто попало

    Spritz Ноя. 13, 2011, 11:16 п.п.

    'SELECT (SELECT SUM(`amount`) FROM `balance_operations` WHERE `type` = 3 AND YEARWEEK(`date`,3) = YEARWEEK(NOW(),3) AND `user_id` = 1) - (SELECT SUM(`amount`) FROM `balance_operations` WHERE `type` = 4 AND YEARWEEK(`date`,3) = YEARWEEK(NOW(),3) AND `user_id` = 1) AS `diff`'

    Как сократить эту хуиту?
  • Faster

    Сообщения: 1159 Репутация: N Группа: Кто попало

    Spritz Ноя. 14, 2011, 4:06 д.п., спустя 4 часа 50 минут 5 секунд

    по всей видимости писать разность сразу в таблицу из которой идет главный селект
  • phpdude

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz Ноя. 14, 2011, 4:16 д.п., спустя 9 минут 24 секунды


    по всей видимости писать разность сразу в таблицу из которой идет главный селект
    Бредовый совет =)
    Сапожник без сапог
  • phpdude

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz Ноя. 14, 2011, 4:27 д.п., спустя 11 минут 14 секунд

    
    SELECT SUM('amount') `diff` FROM (
           SELECT IF(`type` = 3, `amount`, -`amount`) `diff` FROM `balance_operations` WHERE 
                `type` IN (3,4) AND YEARWEEK(`date`,3) = YEARWEEK(NOW(),3) AND `user_id` = 1
           ) `total`
    
    Думаю как то так будет работать =)

    из плюса - не надо будет дважды таблицу проходить как у тебя в примере :-)
    ну и если проставить индекс по всем колонкам которые есть в запросе, то думаю будет работать очень быстро на почти любых размерах базы. но тут конечно надо проверять и explain =)
    Сапожник без сапог
  • lowfuck

    Сообщения: 20 Репутация: N Группа: Кто попало

    Spritz Ноя. 14, 2011, 8:57 п.п., спустя 16 часов 29 минут 56 секунд

    phpdude, спасибо бро!
  • lowfuck

    Сообщения: 20 Репутация: N Группа: Кто попало

    Spritz Ноя. 14, 2011, 9:10 п.п., спустя 12 минут 59 секунд

    Заработало так:
    SELECT SUM(`diff`) `diff` FROM (
           SELECT IF(`type` = 3, `amount`, -`amount`) `diff` FROM `balance_operations` WHERE 
                `type` IN (3,4) AND YEARWEEK(`date`,3) = YEARWEEK(NOW(),3) AND `user_id` = 1
           ) `total`
  • master

    Сообщения: 3244 Репутация: N Группа: Джедаи

    Spritz Ноя. 15, 2011, 11:38 д.п., спустя 14 часов 28 минут 7 секунд

    AND YEARWEEK(`date`,3)

    сколько раз твердили миру, что функций в where надо избегать например
    не всё полезно, что в swap полезло
  • phpdude

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz Ноя. 15, 2011, 2:44 п.п., спустя 3 часа 5 минут 52 секунды

    master, почему? :-)

    Сапожник без сапог
  • Nyaah

    Сообщения: 574 Репутация: N Группа: Джедаи

    Spritz Ноя. 15, 2011, 5:41 п.п., спустя 2 часа 56 минут 51 секунду

    дуд нуб )
    Work, buy, consume, die
  • phpdude

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz Ноя. 15, 2011, 6:12 п.п., спустя 31 минуту 41 секунду

    Nyaah, ага :)
    Сапожник без сапог
  • master

    Сообщения: 3244 Репутация: N Группа: Джедаи

    Spritz Ноя. 15, 2011, 8:56 п.п., спустя 2 часа 44 минуты 13 секунд

    phpdude,
    индексы не используются. сравни на любой таблице с данными
    explain select * from `table` where id=1

    explain select * from `table` where id+1=2
    не всё полезно, что в swap полезло
  • phpdude

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz Ноя. 15, 2011, 10:15 п.п., спустя 1 час 18 минут 28 секунд

    индексы не используются

    спасибо кэп
    Сапожник без сапог
  • lowfuck

    Сообщения: 20 Репутация: N Группа: Кто попало

    Spritz Ноя. 23, 2011, 11:27 п.п., спустя 8 дней 1 час 12 минут

    EXPLAIN


    Ну и как избавиться от использования функций в данном случае например?
  • phpdude

    Сообщения: 26646 Репутация: N Группа: в ухо

    Spritz Ноя. 23, 2011, 11:31 п.п., спустя 3 минуты 39 секунд

    lowfuck, подготовить данные при инсерте/апдейте. то есть завести колонку которая нужна - неделя года. и по ней выбирать :-)
    Сапожник без сапог
  • lowfuck

    Сообщения: 20 Репутация: N Группа: Кто попало

    Spritz Ноя. 23, 2011, 11:48 п.п., спустя 17 минут 50 секунд

    phpdude, понял. Ещё вопрос:

    Если из псевдотаблицы извлекается одно значения, я могу заапдейтить так:
    UPDATE `stat` SET `profit_rur` = (SELECT SUM(`diff`)*0.5 FROM (
           SELECT IF(`type` = 3, `amount`, -`amount`) AS `diff` FROM `balance_operations` WHERE 
                `type` IN (3,4) AND YEARWEEK(`date`,3) = YEARWEEK(NOW(),3) AND `currency` = "rur" AND `user_id` = 1
           ) AS `total`) WHERE `user_id` = 1;


    Но как мне быть, если я хочу заапдейтить сразу 2:

    SELECT SUM(`diff_rur`)*0.5 `total_rur`, SUM(`diff_usd`)*0.5 `total_usd` FROM (
           SELECT IF(`currency` = 'rur', IF(`type` = 3, `amount`, -`amount`), 0) AS `diff_rur`,
           		  IF(`currency` = 'usd', IF(`type` = 3, `amount`, -`amount`), 0) AS `diff_usd`
    		 FROM `balance_operations` WHERE 
                `type` IN (3,4) AND YEARWEEK(`date`,3) = YEARWEEK(NOW(),3) AND `user_id` = 1
           ) AS `total`;
    UPDATE `stat` SET `profit_rur` = `total_rur`, `profit_usd` = `total_usd` WHERE `user_id` = 1;
    


    Хуёво объяснил, надеюсь вы поняли

Пожалуйста, авторизуйтесь, чтобы написать комментарий!