簡體   English   中英

mysql查詢運行非常慢。 請幫我索引

[英]mysql query running very slow. Please help me with indexes

我正在嘗試運行一個查詢,該查詢需要5秒鍾來執行100000行。 查詢如下。 我已經嘗試了所有可能的索引。 請建議我我想念的是什么。

select distinct db_books.bookid as id
, request_type.name as book_type
, request_type.id as book_type_id
, db_books.subject as subject
, sender_user.uid as sender_user_id
, sender_user.username as sender_user
, sender_company.companyid as sender_company_id
, sender_company.companyname as sender_company
, sender_team_id.teamid as sender_team_id
, sender_team_id.name as sender_team
, GROUP_CONCAT(distinct receiver_user_details.uid separator '|') as receiver_user_id
, GROUP_CONCAT(distinct receiver_user_details.username separator '|') as receiver_user
, GROUP_CONCAT(distinct receiver_company.companyid separator '|') as receiver_company_id
, GROUP_CONCAT(distinct receiver_company.companyname separator '|') as receiver_company
, GROUP_CONCAT(distinct receiver_team_details.teamid separator '|') as receiver_team_id
, GROUP_CONCAT(distinct receiver_team_details.name separator '|') as receiver_team
, status.id as statusid
, status.name as status
, db_books.modifydate as modified_date
, db_books.createddate as creation_date
, state.id as stateid
, state.name as state
, assignee.uid as assignee_user_id
, assignee.username as assignee_user
, purpose.name as purpose
, purpose.id as purposeid
, g.name as entityname
, g.entityid as entityid
from db_books db_books 
inner join db_users sender_user on (sender_user.deleted=0 and sender_user.uid=db_books.sndrUserid)
inner join db_companies sender_company on (sender_company.deleted=0 and sender_company.companyid=db_books.sndrCompanyid)
inner join db_companies receiver_company on (receiver_company.deleted=0 and receiver_company.companyid=db_books.target_company_id)
inner join db_request_types request_type on (request_type.id=db_books.book_type_id)
left outer join db_teams sender_team_id on (sender_team_id.deleted=0 and sender_team_id.teamid=db_books.sender_team_id)
left outer join db_books_to_users receiver_user on (receiver_user.bookid=db_books.bookid)
left outer join db_users receiver_user_details on (receiver_user_details.uid=receiver_user.userid)
left outer join db_books_to_teams receiver_teams on (receiver_teams.bookid=db_books.bookid)
left outer join db_teams receiver_team_details on (receiver_team_details.teamid=receiver_teams.teamid)
left outer join db_request_status status on (status.id=db_books.statusid)
left outer join db_request_state_types state on (state.id=db_books.request_state_id)
left outer join db_request_purpose purpose on (purpose.id=db_books.request_purpose_id)
left outer join db_users assignee on (assignee.uid=db_books.assignee)
left outer join db_books_details mdtl on (mdtl.deleted=0 and mdtl.bookid=db_books.bookid)
left outer join db_entities g on (g.deleted=0 and g.entityid=mdtl.entityid)
where 1=1 
and 
(db_books.sndrUserid=25000000003265 
or db_books.sender_team_id in (
            select a.teamid from db_team_users a 
            inner join db_teams b  on (b.teamid=a.teamid and b.deleted=0)
            where a.userid=25000000003265
        )
or db_books.bookid in (
    select distinct bookid from db_books_to_users where userid=25000000003265
    union 
    select distinct bookid from db_books_to_teams where teamid in 
        (
            select a.teamid from db_team_users a 
            inner join db_teams b  on (b.teamid=a.teamid and b.deleted=0)
            where a.deleted=0 AND a.userid=25000000003265
        )
    )
) 
group by db_books.bookid
limit 20

解釋計划如下。

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   PRIMARY sender_user ALL PRIMARY,u2              14573   Using where; Using temporary; Using filesort
1   PRIMARY db_books    ref i_db_books_target_company_id,i_db_books_sndrUserid,i_db_books_sndrCompanyid,i_sndrUserid_sender_team_idbookid   i_db_books_sndrUserid   7   mde_staging.sender_user.uid 41  Using where
1   PRIMARY sender_company  eq_ref  PRIMARY,db_companies_icd    PRIMARY 7   mde_staging.db_books.sndrCompanyid  1   Using where
1   PRIMARY receiver_company    eq_ref  PRIMARY,db_companies_icd    PRIMARY 7   mde_staging.db_books.target_company_id  1   Using where
1   PRIMARY sender_team_id  eq_ref  PRIMARY,db_teams_i  PRIMARY 7   mde_staging.db_books.sender_team_id 1   
1   PRIMARY receiver_user   ref i_db_books_to_users_bookid  i_db_books_to_users_bookid  7   mde_staging.db_books.bookid 1   
1   PRIMARY receiver_user_details   eq_ref  PRIMARY,u2  PRIMARY 7   mde_staging.receiver_user.userid    1   
1   PRIMARY receiver_teams  ref i_db_books_to_teams_bookid  i_db_books_to_teams_bookid  7   mde_staging.db_books.bookid 1   
1   PRIMARY receiver_team_details   eq_ref  PRIMARY,db_teams_i  PRIMARY 7   mde_staging.receiver_teams.teamid   1   
1   PRIMARY status  eq_ref  PRIMARY PRIMARY 4   mde_staging.db_books.statusid   1   
1   PRIMARY state   eq_ref  PRIMARY PRIMARY 4   mde_staging.db_books.request_state_id   1   
1   PRIMARY purpose eq_ref  PRIMARY PRIMARY 4   mde_staging.db_books.request_purpose_id 1   
1   PRIMARY assignee    eq_ref  PRIMARY,u2  PRIMARY 7   mde_staging.db_books.assignee   1   
1   PRIMARY mdtl    ref db_books_details_bookid db_books_details_bookid 7   mde_staging.db_books.bookid 1   
1   PRIMARY request_type    ALL PRIMARY             4   Using where; Using join buffer
1   PRIMARY g   eq_ref  PRIMARY,db_entities7    PRIMARY 7   mde_staging.mdtl.entityid   1   
3   DEPENDENT SUBQUERY  db_books_to_users   ref i_db_books_to_users_bookid  i_db_books_to_users_bookid  7   func    1   Using where; Using temporary
4   DEPENDENT UNION db_books_to_teams   ref i_db_books_to_teams_bookid  i_db_books_to_teams_bookid  7   func    1   Using where; Using temporary
5   DEPENDENT SUBQUERY  b   eq_ref  PRIMARY,db_teams_i  PRIMARY 7   func    1   Using where
5   DEPENDENT SUBQUERY  a   ref db_team_users_i db_team_users_i 11  func,const  1   Using where
    UNION RESULT    <union3,4>  ALL                     
2   DEPENDENT SUBQUERY  b   eq_ref  PRIMARY,db_teams_i  PRIMARY 7   func    1   Using where
2   DEPENDENT SUBQUERY  a   ref db_team_users_i db_team_users_i 7   func    1   Using where

如果您看到解釋計划的第一行,則它沒有使用可能的索引,然后使用文件排序等。不確定是否是問題所在。 請建議我如何解決這個問題或我要使用什么索引?

我看到的最大問題是子查詢限定符。 每一行測試的點擊率。 然后,我將WHERE子句部分更改為僅作為第一個表的預查詢,並獲得這些結果書並加入書中,其余的應該沒問題。 另外,子句“ STRAIGHT_JOIN”告訴引擎按照您說的順序進行查詢。 有時,它會領先於您,並嘗試根據“查找”參考表之一進行優化,然后回填以查找其余部分。 這么說

將頂部的選擇更改為

select STRAIGHT_JOIN distinct 

然后您的from子句來自

   from 
      db_books db_books 

   from
      ( SELECT distinct db.bookid
           from 
              db_books db
                 left join db_team_users TeamA
                     ON db.sndrUserID = TeamA.userID
                    AND db.Sender_Team_ID = TeamA.TeamID
                    LEFT JOIN db_teams TeamB
                        ON TeamA.TeamID = TeamB.TeamID 
                       AND TeamB.Deleted = 0
                 left join db_books_to_users ToUser
                     ON db.BookID = ToUser.BookID
                    AND db.sndrUserID = ToUser.userID
                 left join db_books_to_teams ToTeamA
                     ON db.TeamID = ToTeamA.TeamID
                     AND db.sndrUserID = ToTeamA.UserID
                     AND a.Deleted = 0
                     left join db_teams ToTeamsB
                        ON ToTeamA.TeamID = ToTeamB.TeamID
                        AND b.Deleted = 0
           where 
                 db.sndrUserID = 25000000003265
              OR NOT TeamB.TeamID IS NULL
              OR NOT ToUser.BookID IS NULL
              OR NOT ToTeamB.TeamID IS NULL 
           limit 
              20 ) PreQualBooks
      JOIN db_books
         ON PreQualBooks.BookID = db_Books.BookID

而且,您可以刪除Final WHERE子句,因為該預查詢將一次完成,從而可以根據用戶或團隊與JOIN的關系對每個可能的書ID進行預認證。 通過允許LEFT JOIN,books表通過ONCE,並具有與團隊/用戶狀態的所有各個關系,並且僅基於發送用戶或各個LEFT JOIN的最低級別(TeamB,ToUser和ToTeamB)返回那些記錄。 此預查詢還將限制應用於20本書,因此也不需要查詢末尾的LIMIT子句,因為只有20本書才是可能的。

由於您的group_concat,請離開您的外部GROUP BY。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM