2014-02-19 47 views
0

我有一個查詢,這是非常緩慢INNER JOIN條件,但是在IN子句中使用時更快:如何在條件轉換爲INNER JOIN條件 - 加盟較慢

慢內連接:

SELECT * 
FROM cases 
left join 
(
    select tst.team_set_id 
    from team_sets_teams tst 
    INNER JOIN team_memberships team_memberships 
    ON tst.team_id = team_memberships.team_id 
     AND team_memberships.user_id = '1' 
     AND team_memberships.deleted=0 group by tst.team_set_id 
) cases_tf 
ON cases_tf.team_set_id = cases.team_set_id 
LEFT JOIN contacts_cases 
ON contacts_cases.case_id = cases.id 
    AND contacts_cases.deleted = 0 
where cases.deleted=0 
ORDER BY cases.name LIMIT 0,20; 

更快其中:

SELECT * 
FROM cases 
LEFT JOIN contacts_cases 
ON contacts_cases.case_id = cases.id 
    AND contacts_cases.deleted = 0 
where cases.deleted=0 
    and cases.team_set_id in (
      select tst.team_set_id 
      from team_sets_teams tst 
      INNER JOIN team_memberships team_memberships 
      ON tst.team_id = team_memberships.team_id 
       AND team_memberships.user_id = '1' 
       AND team_memberships.deleted=0 
      group by tst.team_set_id 
) 
ORDER BY cases.name LIMIT 0,20; 

的解釋INNER計劃JOIN和WHERE IN子句低於:

內加入:

+----+-------------+------------------+------+--------------------------------------------+---------------------+---------+-----------------------------------+--------+----------------------------------------------+ 
| id | select_type | table   | type | possible_keys        | key     | key_len | ref        | rows | Extra          | 
+----+-------------+------------------+------+--------------------------------------------+---------------------+---------+-----------------------------------+--------+----------------------------------------------+ 
| 1 | PRIMARY  | <derived2>  | ALL | NULL          | NULL    | NULL | NULL        |  4 | Using temporary; Using filesort    | 
| 1 | PRIMARY  | cases   | ref | idx_cases_tmst_id       | idx_cases_tmst_id | 109  | cases_tf.team_set_id    | 446976 | Using where         | 
| 1 | PRIMARY  | contacts_cases | ref | idx_con_case_case       | idx_con_case_case | 111  | sugarcrm.cases.id     |  1 |            | 
| 2 | DERIVED  | team_memberships | ref | idx_team_membership,idx_teammemb_team_user | idx_team_membership | 109  |         |  2 | Using where; Using temporary; Using filesort | 
| 2 | DERIVED  | tst    | ref | idx_ud_team_id        | idx_ud_team_id  | 109  | sugarcrm.team_memberships.team_id |  1 | Using where         | 
+----+-------------+------------------+------+--------------------------------------------+---------------------+---------+-----------------------------------+--------+----------------------------------------------+ 

雖然條件:

------+-----------------------------------+------+----------------------------------------------+ 
| id | select_type  | table   | type | possible_keys        | key     | key_len | ref        | rows | Extra          | 
+----+--------------------+------------------+-------+--------------------------------------------+---------------------+---------+-----------------------------------+------+----------------------------------------------+ 
| 1 | PRIMARY   | cases   | index | NULL          | idx_case_name  | 768  | NULL        | 20 | Using where         | 
| 1 | PRIMARY   | contacts_cases | ref | idx_con_case_case       | idx_con_case_case | 111  | sugarcrm.cases.id     | 1 |            | 
| 2 | DEPENDENT SUBQUERY | team_memberships | ref | idx_team_membership,idx_teammemb_team_user | idx_team_membership | 109  | const        | 2 | Using where; Using temporary; Using filesort | 
| 2 | DEPENDENT SUBQUERY | tst    | ref | idx_ud_team_id        | idx_ud_team_id  | 109  | sugarcrm.team_memberships.team_id | 1 | Using where         | 
+----+--------------------+------------------+-------+--------------------------------------------+---------------------+---------+-----------------------------------+------+----------------------------------------------+ 

雖然有指標,我無法弄清楚什麼問題。請幫助我。謝謝。 (這是在sugarcrm中的查詢)

回答

1

不可能將IN條件轉換爲INNER JOIN

帶有IN條件的查詢稱爲半連接
半連接從一個表中返回將與另一個表連接的行,但不執行完整連接。

下面是一個簡單的例子的半聯接使用IN操作查詢:

SELECT * 
FROM table1 
WHERE some-column IN (
    SELECT some-other-column 
    FROM table2 
    WHERE some-conditions 
) 

上述半聯接可被轉化爲語義上等價查詢
(eqivalent - 意味着giving exactly same results
使用EXISTS操作和dependend子查詢:

SELECT * 
FROM table1 
WHERE EXISTS(
    SELECT 1 
    FROM table2 
    WHERE some-conditions 
    AND table1.some-column = table2.some-other-column 
) 

最領先的數據庫使用相同的計劃,上述兩種查詢,他們的速度是一樣的,
不幸的是,MySql並不總是這樣。

聯接和半聯接是完全不同的查詢,具有完全不同的執行計劃,因此比較它們的速度就像比較蘋果和洋蔥。

您可以嘗試使用IN將第一個查詢轉換爲帶有EXIST的查詢,但不能轉換爲連接。

+0

謝謝,但我們最終完全刪除了團隊條件。 – Paramesh