[英]Extremely slow select query from 3 left joins
我的選擇查詢速度很慢,並且我嘗試了很多方法來加快它的速度,但是執行它仍然需要幾分鍾 。 我將解釋表格和我嘗試過的內容。 我想知道是否有更有效的方法來組織此相當簡單的查詢。
大約有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
非常感謝任何支持。
雖然較小,但是您仍然有可能過度使用括號...這里是從/聯接處修改的
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 ...這樣,至少您將首先加入該客戶,然后該客戶中的職位。
我設法使用觸發器解決了這個問題。 我沒有使用那些昂貴的OR,而只是在稱為link_id
positions
添加了一個列,其中通過使用以下方法添加了covered_positions
的id
:
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
$$
和
DELIMITER $$
CREATE TRIGGER covereds_after_delete
AFTER DELETE ON covered_positions
FOR EACH ROW
BEGIN
UPDATE positions
SET link_id = NULL
WHERE positions.id
IN (OLD.linked_id1, OLD.linked_id2, OLD.linked_id3, OLD.linked_id4, OLD.linked_id5);
END
$$
這樣,查詢不會將18,000行變成大約400萬行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.