以下查询获取我需要的信息。但是,我注意到随着表的增长,我的代码越来越慢。我猜它是这个查询。这可以用不同的方式来提高效率吗?我听说过很多关于使用连接而不是子查询的事情,但是,我并没有“得到”如何做到这一点。
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
答案 0 :(得分:0)
我会将查询分成更小的块,可能使用存储过程。例如,从事务中获取max ids并将其放入表变量中。然后将其与子事务联系起来。这将使您和编译器更容易计算出正在发生的事情。 也不知道你的桌子上有什么索引,很难提供更多建议
答案 1 :(得分:0)
您的代码:
(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
的最大ID。
然后您将所有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)
中有十个唯一的transaction
,那么您将获得100行。 1000个独特的位置,一百万行。等
如果你想编写一个像这样的复杂查询,如果你用简单的视图编写它就会容易得多。特别是,您可以自己测试每个视图,以确保获得合理的结果,然后加入视图。
答案 2 :(得分:0)
在代码中放置一个基准函数。然后计算代码的每个部分以确定减速发生的位置。通常情况下,减速发生在与您第一次猜测不同的查询中。确定在发布到stackoverflow之前需要优化的正确查询。