我有一个非常慢的选择查询,我已经尝试了很多东西来加快速度,但它仍然需要分钟才能执行。我会解释表格以及我尝试过的内容。我想知道是否有更有效的方法来组织这个相当简单的查询。
大约有18000行。
职位基本上由经纪人拥有的客户拥有,因此要将职位链接到经纪人,我们会通过clients
表。我正在显示与相应经纪人的头寸,以及他们是否通过covered_positions
链接到另一个头寸,以及哪个头寸被挂钩(如果有的话)。
positions
包含客户完成的所有交易(股票/期权)。它有一个PK positionsID
(AI),但MySQL似乎并不认为它是可能的索引。探索结果如下。clients
包含所有客户信息(客户)。它有PK clientsID
(AI),它是positions
中的外键。login_users
包含经纪人(员工)。它具有PK user_id
(AI),它是clients
中broker_id
的外键。covered_positions
包含2-5个位置之间的链接(不是超链接)。它有PK covered_id
(AI)。 linked_id*
列是已链接在一起的positionsID
。delimiter $$
CREATE VIEW `main_join3` AS
select `positions`.`id` AS `positionsID`,
`positions`.`order_list` AS `order_list`,
`positions`.`client_id` AS `client_id`,
`positions`.`client_name` AS `client_name`,
`positions`.`broker_name` AS `pos_broker_name`,
`positions`.`account_status` AS `pos_account_status`,
`positions`.`cost_basis` AS `cost_basis`,
`positions`.`cost_per_share` AS `cost_per_share`,
`positions`.`security` AS `security`,
`positions`.`security_type` AS `security_type`,
`positions`.`strike_price` AS `strike_price`,
`positions`.`option_type` AS `option_type`,
`positions`.`exp_month` AS `exp_month`,
`positions`.`exp_year` AS `exp_year`,
`positions`.`exp_date` AS `exp_date`,
`positions`.`buy_shares` AS `buy_shares`,
`positions`.`buy_date` AS `buy_date`,
`positions`.`buy_price` AS `buy_price`,
`positions`.`buy_commission` AS `buy_commission`,
`positions`.`buy_misc` AS `buy_misc`,
`positions`.`buy_cost` AS `buy_cost`,
`positions`.`sell_shares` AS `sell_shares`,
`positions`.`sell_date` AS `sell_date`,
`positions`.`sell_price` AS `sell_price`,
`positions`.`sell_commission` AS `sell_commission`,
`positions`.`sell_misc` AS `sell_misc`,
`positions`.`sell_cost` AS `sell_cost`,
`positions`.`loss` AS `loss`,
`positions`.`profit` AS `profit`,
`positions`.`funds_in_out` AS `funds_in_out`,
`positions`.`funds_in` AS `funds_in`,
`positions`.`funds_out` AS `funds_out`,
`positions`.`stop_order` AS `stop_order`,
`positions`.`notes` AS `notes`,
`positions`.`orange_highlight` AS `orange_highlight`,
`positions`.`date_created` AS `pos_date_created`,
`positions`.`date_updated` AS `pos_date_updated`,
`positions`.`created_by_id` AS `pos_cb_id`,
`positions`.`created_by_name` AS `pos_cb_name`,
`clients`.`id` AS `clientsID`,
`clients`.`broker_id` AS `broker_id`,
`clients`.`account_status` AS `clients_account_status`,
`login_users`.`user_id` AS `user_id`,
`login_users`.`user_level` AS `user_level`,
`login_users`.`username` AS `username`,
`login_users`.`name` AS `name`,
`covered_positions`.`id` AS `covered_id`,
`covered_positions`.`linked_id1` AS `linked_id1`,
`covered_positions`.`linked_id2` AS `linked_id2`,
`covered_positions`.`linked_id3` AS `linked_id3`,
`covered_positions`.`linked_id4` AS `linked_id4`,
`covered_positions`.`linked_id5` AS `linked_id5`
from (((`positions`
left join `clients`
on((`positions`.`client_id` = `clients`.`id`)))
left join `login_users`
on((`clients`.`broker_id` = `login_users`.`user_id`)))
left join `covered_positions`
on(((`positions`.`id` = `covered_positions`.`linked_id1`)
or (`positions`.`id` = `covered_positions`.`linked_id2`)
or (`positions`.`id` = `covered_positions`.`linked_id3`)
or (`positions`.`id` = `covered_positions`.`linked_id4`)
or (`positions`.`id` = `covered_positions`.`linked_id5`))))$$
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE positions ALL NULL NULL NULL NULL 18070
1 SIMPLE clients eq_ref PRIMARY PRIMARY 4 blackri_posting.positions.client_id 1
1 SIMPLE login_users eq_ref PRIMARY,user_id PRIMARY 4 blackri_posting.clients.broker_id 1
1 SIMPLE covered_positions ALL NULL NULL NULL NULL 214
非常感谢任何支持。
答案 0 :(得分:1)
虽然很小,但你有过度使用括号......这是从/ join
修改的from
positions
left join clients
ON positions.client_id = clients.id
left join login_users
ON clients.broker_id = login_users.user_id
left join covered_positions
ON positions.id = covered_positions.linked_id1
or positions.id = covered_positions.linked_id2
or positions.id = covered_positions.linked_id3
or positions.id = covered_positions.linked_id4
or positions.id = covered_positions.linked_id5
其次,只是为了咧嘴笑,尝试将MySQL关键字“STRAIGHT_JOIN”添加到您的查询......
SELECT STRAIGHT_JOIN(查询的其余部分)
第三,你的桌子“Covered_positions” 您是否在每个linked_id列上都有索引。如果无法在连接上使用索引,那么这将使您的查询爬行。
最后,如果您的覆盖位置表具有客户端ID,我绝对会将其添加为索引中的第一个字段并在连接中包含客户端ID ...这样,至少您将加入客户端首先,然后是该客户的职位。
答案 1 :(得分:0)
我设法使用触发器来解决问题。我只是在名为positions
的{{1}}中添加了一个列,而不是使用那些代价高昂的OR,其中link_id
来自id
,其中使用了以下内容:
covered_positions
和
DELIMITER $$
CREATE TRIGGER covereds_after_insert
AFTER INSERT ON covered_positions
FOR EACH ROW
BEGIN
UPDATE positions
SET link_id = NEW.id
WHERE positions.id
IN (NEW.linked_id1, NEW.linked_id2, NEW.linked_id3, NEW.linked_id4, NEW.linked_id5);
END
$$
这样查询就不会将18,000行变成大约400万行。