Как мне оптимизировать этот запрос? - PullRequest
0 голосов
/ 24 января 2011

Следующий запрос получает информацию, которая мне нужна.Однако я заметил, что по мере роста таблиц мой код становится все медленнее и медленнее.Я предполагаю, что это этот запрос.Может ли это быть написано по-другому, чтобы сделать его более эффективным?Я много слышал об использовании объединений вместо подзапросов, однако я не понимаю, как это сделать.

  SELECT * FROM

  (SELECT MAX(T.id) AS MAXid
  FROM transactions AS T 
  GROUP BY T.position
  ORDER BY T.position) AS result1,

  (SELECT T.id AS id, T.symbol, T.t_type, T.degree, T.position, T.shares, T.price, T.completed, T.t_date,
  DATEDIFF(CURRENT_DATE, T.t_date) AS days_past, 
  IFNULL(SUM(S.shares), 0) AS subtrans_shares,
  T.shares - IFNULL(SUM(S.shares),0) AS due_shares,

  (SELECT IFNULL(SUM(IF(SO.t_type = 'sell', -SO.shares, SO.shares )), 0) 
  FROM subtransactions AS SO WHERE SO.symbol = T.symbol) AS owned_shares

  FROM transactions AS T
  LEFT OUTER JOIN subtransactions AS S
  ON T.id = S.transid     
  GROUP BY T.id
  ORDER BY T.position) AS result2

  WHERE MAXid = id

Ответы [ 3 ]

0 голосов
/ 25 января 2011

Ваш код:

  (SELECT MAX(T.id) AS MAXid
  FROM transactions AS T        [<--- here ]
  GROUP BY T.position
  ORDER BY T.position) AS result1,

  (SELECT T.id AS id, T.symbol, T.t_type, T.degree, T.position, T.shares, T.price, T.completed, T.t_date,
  DATEDIFF(CURRENT_DATE, T.t_date) AS days_past, 
  IFNULL(SUM(S.shares), 0) AS subtrans_shares,
  T.shares - IFNULL(SUM(S.shares),0) AS due_shares,

  (SELECT IFNULL(SUM(IF(SO.t_type = 'sell', -SO.shares, SO.shares )), 0) 
  FROM subtransactions AS SO WHERE SO.symbol = T.symbol) AS owned_shares

  FROM transactions AS T     [<--- here ]

Обратите внимание на отметки [<---- here ], которые я добавил к вашему коду.

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

Итак, что вы делаете в первом, некоррелированном подзапросе?получение максимального идентификатора для всех positions в transactions.

И затем вы соединяете все transaction.position.max(id) с result2 (который result2 является объединением всех transaction.position с subtransactions).(И внутренний order by тоже бессмыслен и дорог, но это не главная проблема.)

Вы присоединяете каждый transaction.position.max(id) к каждому (какой бы результат не выбрал 2).

При редактировании, после возвращения домой : Хорошо, вы не декартово, "где MAXid = id" присоединяется result1 к result2.Но вы по-прежнему скручиваете все строки transaction в обоих запросах.

Таким образом, вы получаете декартово соединение - каждое result1 присоединяется к каждому result2, безусловно (ничегонапример, сообщает базе данных, что они должны быть объединены (max) id или по позиции).

Так что если у вас есть десять уникальных position.max(id) s в transaction, вы получите 100 строк,1000 уникальных позиций, миллион строк.И т.д.

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

0 голосов
/ 26 января 2011

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

0 голосов
/ 25 января 2011

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

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