簡體   English   中英

如何提高MySQL查詢的速度?

[英]How can I improve the speed of this MySQL query?

這是查詢:

SELECT 
u.uid as UID,
fuo.uid as FUO_UID,
fo.prid as FO_NAME
FROM 
users u
LEFT OUTER JOIN firstpoint_users_organisations fuo ON (u.uid=fuo.uid)
LEFT OUTER JOIN firstpoint_organisations fo ON (fo.nid=fuo.nid)
WHERE 
u.status=1 AND u.uid>1 
ORDER BY u.uid 
LIMIT 3;

表格:

users
+------------------+------------------+------+-----+---------+----------------+
| Field            | Type             | Null | Key | Default | Extra          |
+------------------+------------------+------+-----+---------+----------------+
| uid              | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| name             | varchar(60)      | NO   | UNI |         |                |
| status           | tinyint(4)       | NO   |     | 0       |                |
+-----------------------------------------------------------------------------+

firstpoint_users_organisations
+-------+------------------+------+-----+---------+-------+
| Field | Type             | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+-------+
| nid   | int(10) unsigned | NO   | PRI | 0       |       |
| uid   | int(10) unsigned | NO   | PRI | 0       |       |
+-------+------------------+------+-----+---------+-------+

firstpoint_organisations
+----------+------------------+------+-----+---------+-------+
| Field    | Type             | Null | Key | Default | Extra |
+----------+------------------+------+-----+---------+-------+
| nid      | int(10) unsigned | NO   | PRI | 0       |       |
| prid     | varchar(32)      | NO   |     |         |       |
+------------------------------------------------------------+

我希望為users每一行顯示users.uidfirstpoint_organisations.prid ,即使某些用戶沒有prid ,在這種情況下我顯示NULL(因此左外連接)。 連接應如下:

users
uid -      firstpoint_users_organisations 
     \---->uid
           nid -          firstpoint_organisations
                \-------->nid
                          prid

因此,每個用戶(用戶)都有一個用戶ID(uid),並且他們與之關聯的組織(firstpoint_users_organisation)具有節點ID(nid)並存儲該關聯。 然后,組織的詳細信息將存儲在firstpoint_organisations中。

因此每個用戶都有一個prid ,但如果他們沒有,則顯示NULL。

現在,如果我在firstpoint_users_organisations上執行INNER JOIN,然后在firstpoint_organisations上執行INNER JOIN,我會獲得良好的查詢速度(上述查詢在0.02秒內運行)。 但是,當我切換到LEFT OUTER JOIN,所以我可以獲得所有用戶, prid或沒有prid ,上面的查詢需要大約90秒才能運行。

有什么辦法可以加快查詢速度嗎? 有約。 users表中有70,000行,但即使使用LIMIT 3,使INNER JOIN成為LEFT OUTER JOIN需要花費大量時間。 有趣的是,查詢需要花費相同的時間來運行LIMIT 30,所以我認為我的查詢存在根本性的錯誤。

按要求說明:

+----+-------------+-------+--------+---------------+---------+---------+-----------------------+-------+----------------------------------------------+
| id | select_type | table | type   | possible_keys | key     | key_len | ref                   | rows  | Extra                                        |
+----+-------------+-------+--------+---------------+---------+---------+-----------------------+-------+----------------------------------------------+
|  1 | SIMPLE      | u     | range  | PRIMARY       | PRIMARY | 4       | NULL                  | 13152 | Using where; Using temporary; Using filesort |
|  1 | SIMPLE      | fuo   | index  | NULL          | PRIMARY | 8       | NULL                  |  3745 | Using index                                  |
|  1 | SIMPLE      | fo    | eq_ref | PRIMARY       | PRIMARY | 4       | dbdb-dbdb_uat.fuo.nid |     1 |                                              |
+----+-------------+-------+--------+---------------+---------+---------+-----------------------+-------+----------------------------------------------+
3 rows in set (0.00 sec)

我會在u.status,u.uid上使用一個唯一的索引,因為mysql必須使用fullscan來查看,我認為哪些條目的狀態= 1。

我希望事后更快;)

您的查詢是無意義的(因為uid > 1將包括除一個用戶之外的所有用戶)使用uid上的索引,因此對該索引使用IGNORE INDEX提示:

SELECT 
  u.uid as UID,
  fuo.uid as FUO_UID,
  fo.prid as FO_NAME
FROM users u IGNORE INDEX (uid)
LEFT JOIN firstpoint_users_organisations fuo ON u.uid=fuo.uid
LEFT JOIN firstpoint_organisations fo ON fo.nid=fuo.nid
WHERE u.status=1
AND u.uid > 1 
ORDER BY u.uid 
LIMIT 3

您應該在users(status)上放置索引,如果有足夠的行狀態,則可能會給您帶來一些好處!= 1

非常期望更改LIMIT沒有任何效果,因為應用限制之前必須對70000行進行排序以確定哪些行是要返回的第一行 - 該限制幾乎沒有效果,除了將更少的行返回給客戶端(少逗號IO)


我相信“代碼越少越好”,所以從嚴格的風格角度來看,我已從您的查詢中刪除了非必要的代碼:

  • 刪除了OUTER因為沒有其他類型的左連接
  • 刪除了連接條件周圍的括號,因為您不需要它們

暫無
暫無

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

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