Увеличьте скорость запроса mySQL - PullRequest
2 голосов
/ 30 июня 2011

У меня есть такая таблица.

CREATE TABLE `accounthistory` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `date` datetime DEFAULT NULL,
  `change_ammount` float DEFAULT NULL,
  `account_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
)

Это список ежедневных платежей за аккаунт.Если мне нужен остаток на счете, я использую SELECT sum (change_ammount) ОТ accounthistory WHERE account_id =;Это довольно быстро, потому что я добавил индекс в столбце account_id.

Но теперь мне нужно найти время, когда учетная запись стала минусовой (дата, когда SUM (change_ammount) <0).* <pre>SELECT main.date as date from accounthistory as main WHERE main.account_id=484368430 AND (SELECT sum(change_ammount) FROM accounthistory as sub WHERE sub.account_id=484368430 AND sub.date < main.date)<0 ORDER BY main.date DESC LIMIT 1;

Но работает очень медленно.Можете ли вы предложить решение лучше?Может быть, мне нужны индексы (не только для account_id)?

Ответы [ 2 ]

1 голос
/ 01 июля 2011

Чтобы ускорить ваш запрос, используйте денормализация : сохраняйте баланс текущего счета в каждой записи.Для этого вам нужно сделать три вещи, а затем мы посмотрим, как будет выглядеть запрос:

a) Добавить столбцы в таблицу:

ALTER TABLE accounthistory ADD balance float;

b) Заполните новый столбец

UPDATE accounthistory main SET
balance = (
    SELECT SUM(change_amount)
    FROM accounthistory
    where account_id = main.account_id
    and data <= main.date
);

в) Чтобы заполнить новые строки, либо: а) используйте триггер, б) используйте логику приложения, либо в) выполните приведенный выше оператор UPDATE для строки, добавленной после добавленияэто, т. е. UPDATE ... WHERE id = ?

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

SELECT date
from accounthistory
where balance < 0
and balance - change_amount > 0
and account_id = ?;
0 голосов
/ 30 июня 2011
SELECT MAX(main.date) as date 
from accounthistory as main
WHERE main.account_id=484368430
      AND EXISTS (SELECT 1 FROM accounthistory as sub
                           WHERE sub.account_id=main.account_id AND
                                 sub.date < main.date HAVING SUM(sub.change_ammount) < 0)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...