簡體   English   中英

在MySQL中快速查詢但在PHP中緩慢查詢

[英]Query fast in MySQL but slow in PHP

我們的網站之一上的搜索引擎非常慢。 我打開了慢速查詢日志,並記錄了所有耗時超過10秒的查詢。 僅記錄來自此搜索引擎的查詢。 這是日志的一個示例:

# Time: 120801  9:21:42
# User@Host: ********** @ localhost []
# Query_time: 22.156250  Lock_time: 0.000000 Rows_sent: 33  Rows_examined: 3385401
SET timestamp=1343805702;
SELECT *, IF(InSection OR InBranche, 1, 0) AS SorteerKolom FROM(SELECT DISTINCT Plant, Email, Nicename, Displayname, JobTitle, Department, Initials, Lastname, LastnameForSort, 
                                search_people.ForeignId, IsVennoot, 
                                (Zoekwoorden LIKE '%statutair%') AS SearchTerm, 
                                (Displayname LIKE '%statutair%') AS ByName, 
                                0 AS InSection, 0 AS InBranche, 1 AS ShowAll, 
                                (SELECT COUNT(*) FROM search_hasarticles WHERE UserId = search_people.ForeignId) > 0 AS HasWritten 
                             FROM search_people 
                             LEFT JOIN search_people_branches ON search_people.ForeignId = search_people_branches.UserId 
                             LEFT JOIN search_people_specialismen ON search_people.ForeignId = search_people_specialismen.UserId 
                             LEFT JOIN wp_usermeta AS wpu ON (wpu.user_id = search_people.ForeignId)
                             WHERE 
                             (
                                Firstname LIKE '%statutair%' 
                                OR Lastname LIKE '%statutair%' 
                                AND Displayname LIKE '%statutair%' 
                                OR Email LIKE '%statutair%' 
                                OR Address LIKE '%statutair%' 
                                OR Initials LIKE '%statutair%' 
                                OR Location LIKE '%statutair%' 
                                OR Givenname LIKE '%statutair%' 
                                OR Nickname LIKE '%statutair%' 
                                OR JobTitle LIKE '%statutair%' 
                                OR Login LIKE '%statutair%' 
                                OR Title LIKE '%statutair%' 
                                OR Phone LIKE '%statutair%' 
                                OR Fax LIKE '%statutair%' 
                                OR Plant LIKE '%statutair%' 
                                OR Displayname LIKE '%statutair%' 
                                OR Zoekwoorden LIKE '%statutair%'

                             )
                             AND (1=1) AND search_people.IsHidden = 0 AND search_people.Activated = 1 UNION SELECT DISTINCT Plant, Email, Nicename, Displayname, JobTitle, Department, Initials, Lastname, LastnameForSort, 
                                search_people.ForeignId, IsVennoot, 0 AS SearchTerm, 0 AS ByName, 0 AS InSection, 1 AS InBranche, 1 AS ShowAll, 
                                (SELECT COUNT(*) FROM search_hasarticles WHERE UserId = search_people.ForeignId) > 0 AS HasWritten 
                             FROM search_people 
                             LEFT JOIN search_people_branches ON search_people.ForeignId = search_people_branches.UserId 
                             LEFT JOIN search_branches ON search_branches.ForeignId  = search_people_branches.BrancheId 
                             LEFT JOIN search_people_specialismen ON search_people.ForeignId = search_people_specialismen.UserId  
                             WHERE Name LIKE '%statutair%' AND (1=1) AND search_people.IsHidden = 0 AND search_people.Activated = 1 UNION SELECT DISTINCT Plant, Email, Nicename, Displayname, JobTitle, Department, Initials, Lastname, LastnameForSort, search_people.ForeignId, IsVennoot, 0 AS SearchTerm, 0 AS ByName, 1 AS InSection, 0 AS InBranche, 1 AS ShowAll, (SELECT COUNT(*) FROM search_hasarticles WHERE UserId = search_people.ForeignId) > 0 AS HasWritten FROM search_people LEFT JOIN search_people_specialismen ON search_people.ForeignId=search_people_specialismen.UserId LEFT JOIN search_specialties ON search_specialties.ForeignId=search_people_specialismen.SpecialismeId LEFT JOIN search_people_branches ON search_people.ForeignId=search_people_branches.UserId WHERE (Name LIKE '%statutair%' OR SearchTerms LIKE '%statutair%') AND (1=1) AND search_people.IsHidden = 0 AND search_people.Activated = 1 UNION SELECT DISTINCT Plant, Email, Nicename, Displayname, JobTitle, Department, Initials, Lastname, LastnameForSort, search_people.ForeignId, IsVennoot, 0 AS SearchTerm, 0 AS ByName, 0 AS InSection, 0 AS InBranche, 0 AS ShowAll, 1 AS HasWritten FROM search_posts LEFT JOIN search_posts_branches ON search_posts.ForeignId=search_posts_branches.PostId LEFT JOIN search_branches ON search_posts_branches.BrancheId=search_branches.ForeignId LEFT JOIN search_people_specialismen ON search_posts.PostAuthor=search_people_specialismen.UserId LEFT JOIN search_specialties ON search_people_specialismen.SpecialismeId=search_specialties.ForeignId INNER JOIN search_people ON search_people.ForeignId=search_posts.PostAuthor WHERE (PostTitle LIKE '%statutair%' OR PostContent LIKE '%statutair%' OR search_branches.Name LIKE '%statutair%' OR search_specialties.Name LIKE '%statutair%') AND PostStatus='publish' AND PostType='post' AND (1=1) AND search_people.IsHidden = 0 AND search_people.Activated = 1) AS search_results ORDER BY SearchTerm DESC, ByName DESC, SorteerKolom DESC, IsVennoot DESC, InSection DESC, InBranche DESC, HasWritten DESC, LastnameForSort ASC, Initials ASC;

如您所見,執行查詢大約需要22秒鍾,如果直接在MySQL中執行相同的查詢大約需要4秒鍾。

我對相同的查詢做了一個EXPLAIN,並且uotput如下:

id                               select_type                      table                            type                             possible_keys                    key                              key_len                          ref                               rows                             Extra                                    
1                                PRIMARY                          <derived2>                       ALL                              NULL                             NULL                             NULL                             NULL                              33                               Using filesort                           
2                                DERIVED                          search_people                    ALL                              NULL                             NULL                             NULL                             NULL                              323                              Using where; Using temporary             
2                                DERIVED                          search_people_branches           ALL                              NULL                             NULL                             NULL                             NULL                              2013                             Distinct                                 
2                                DERIVED                          search_people_specialismen       ALL                              NULL                             NULL                             NULL                             NULL                              1013                             Distinct                                 
2                                DERIVED                          wpu                              ref                              user_id                          user_id                          8                                wordpress.search_people.ForeignId 84                               Using index; Distinct                    
3                                DEPENDENT SUBQUERY               search_hasarticles               ALL                              NULL                             NULL                             NULL                             NULL                              101                              Using where                              
4                                UNION                            search_branches                  ALL                              NULL                             NULL                             NULL                             NULL                              19                               Using where; Using temporary             
4                                UNION                            search_people                    ALL                              NULL                             NULL                             NULL                             NULL                              323                              Using where; Using join buffer           
4                                UNION                            search_people_specialismen       ALL                              NULL                             NULL                             NULL                             NULL                              1013                             Distinct                                 
4                                UNION                            search_people_branches           ALL                              NULL                             NULL                             NULL                             NULL                              2013                             Using where; Distinct; Using join buffer 
5                                DEPENDENT SUBQUERY               search_hasarticles               ALL                              NULL                             NULL                             NULL                             NULL                              101                              Using where                              
6                                UNION                            search_specialties               ALL                              NULL                             NULL                             NULL                             NULL                              73                               Using where; Using temporary             
6                                UNION                            search_people                    ALL                              NULL                             NULL                             NULL                             NULL                              323                              Using where; Using join buffer           
6                                UNION                            search_people_specialismen       ALL                              NULL                             NULL                             NULL                             NULL                              1013                             Using where; Distinct; Using join buffer 
6                                UNION                            search_people_branches           ALL                              NULL                             NULL                             NULL                             NULL                              2013                             Distinct                                 
7                                DEPENDENT SUBQUERY               search_hasarticles               ALL                              NULL                             NULL                             NULL                             NULL                              101                              Using where                              
8                                UNION                            search_posts                     ALL                              NULL                             NULL                             NULL                             NULL                              15860                            Using where; Using temporary             
8                                UNION                            search_posts_branches            ALL                              NULL                             NULL                             NULL                             NULL                              149                              Distinct                                 
8                                UNION                            search_branches                  ALL                              NULL                             NULL                             NULL                             NULL                              19                               Distinct                                 
8                                UNION                            search_people_specialismen       ALL                              NULL                             NULL                             NULL                             NULL                              1013                             Distinct                                 
8                                UNION                            search_specialties               ALL                              NULL                             NULL                             NULL                             NULL                              73                               Using where; Distinct                    
8                                UNION                            search_people                    ALL                              NULL                             NULL                             NULL                             NULL                              323                              Using where; Distinct; Using join buffer 
                                 UNION RESULT                     <union2,4,6,8>                   ALL                              NULL                             NULL                             NULL                             NULL                              NULL                                                                      

誰能解釋為什么相同的查詢在我的網站上比在MySQL中直接慢得多? 甚至更重要的是,有沒有辦法使此網站上的查詢速度更快?

如果您需要更多信息來進行故障排除,請大聲疾呼,我將盡力提供這些信息。

提前,非常感謝,Jan。

這是查詢的個人資料:

+----------------------+----------+
| Status               | Duration |
+----------------------+----------+
| starting             | 0.000431 |
| Opening tables       | 0.002004 |
| System lock          | 0.000012 |
| Table lock           | 0.000502 |
| optimizing           | 0.000033 |
| statistics           | 0.000042 |
| preparing            | 0.000034 |
| Creating tmp table   | 0.000085 |
| executing            | 0.000004 |
| Copying to tmp table | 0.001957 |
| Sending data         | 0.000006 |
| optimizing           | 0.000025 |
| statistics           | 0.000027 |
| preparing            | 0.000041 |
| Creating tmp table   | 0.000114 |
| executing            | 0.000001 |
| Copying to tmp table | 0.000058 |
| Sending data         | 0.000004 |
| optimizing           | 0.000021 |
| statistics           | 0.000027 |
| preparing            | 0.000037 |
| Creating tmp table   | 0.000095 |
| executing            | 0.000003 |
| Copying to tmp table | 0.007376 |
| optimizing           | 0.000013 |
| statistics           | 0.000017 |
| preparing            | 0.000011 |
| executing            | 0.000005 |
| Sending data         | 0.001248 |
| executing            | 0.000014 |
| Sending data         | 0.001894 |
| executing            | 0.000007 |
| Sending data         | 0.003249 |
| executing            | 0.000004 |
| Sending data         | 0.001487 |
| executing            | 0.000001 |
| Sending data         | 0.000433 |
| executing            | 0.000001 |
| Sending data         | 0.012100 |
| executing            | 0.000006 |
| Sending data         | 0.000713 |
| executing            | 0.000002 |
| Sending data         | 0.000681 |
| executing            | 0.000001 |
| Sending data         | 0.015382 |
| executing            | 0.000005 |
| Sending data         | 0.001048 |
| executing            | 0.000002 |
| Sending data         | 0.000916 |
| executing            | 0.000004 |
| Sending data         | 0.000421 |
| executing            | 0.000001 |
| Sending data         | 0.000561 |
| executing            | 0.000001 |
| Sending data         | 0.005126 |
| executing            | 0.000008 |
| Sending data         | 0.014534 |
| executing            | 0.000004 |
| Sending data         | 0.001666 |
| executing            | 0.000006 |
| Sending data         | 0.001641 |
| Sending data         | 0.000203 |
| optimizing           | 0.000045 |
| statistics           | 0.000050 |
| preparing            | 0.000049 |
| Creating tmp table   | 0.000182 |
| executing            | 0.000002 |
| Copying to tmp table | 5.101209 |
| Sending data         | 0.000226 |
| optimizing           | 0.000007 |
| statistics           | 0.000008 |
| preparing            | 0.000007 |
| executing            | 0.000001 |
| Sending data         | 0.000217 |
| removing tmp table   | 0.000044 |
| Sending data         | 0.000007 |
| removing tmp table   | 0.000012 |
| Sending data         | 0.000017 |
| removing tmp table   | 0.000011 |
| Sending data         | 0.000005 |
| removing tmp table   | 0.000033 |
| Sending data         | 0.000008 |
| removing tmp table   | 0.000030 |
| Sending data         | 0.000009 |
| init                 | 0.000044 |
| optimizing           | 0.000005 |
| statistics           | 0.000004 |
| preparing            | 0.000007 |
| executing            | 0.000002 |
| Sorting result       | 0.000074 |
| Sending data         | 0.000164 |
| end                  | 0.000003 |
| query end            | 0.000005 |
| freeing items        | 0.000210 |
| removing tmp table   | 0.000061 |
| closing tables       | 0.000051 |
| logging slow query   | 0.000003 |
| cleaning up          | 0.000026 |
+----------------------+----------+

我看到很多不可索引的條件,例如Firstname LIKE '%statutair%' 一種可能是MySQL實際上正在使用其結果緩存 ,而PHP無法利用結果緩存。 例如,如果在禁用ATTR_EMULATE_PREPARES選項的情況下使用PDO,則可能會發生這種情況。

要找出答案,請在從MySQL內部進行測試時添加SQL_NO_CACHE子句,如下所示:

SELECT SQL_NO_CACHE id, name FROM customer;

在我看來,您必須在許多列上設置索引。 請閱讀以下內容: http : //dev.mysql.com/doc/refman/5.0/en/explain-output.html為了加快查詢速度,請在JOIN語句中使用的每一列上設置索引。 如果這樣做不能加快速度,請在檢查WHERE所依據的列上設置索引。 而且,OR運算符很慢,並且在具有所有OR的塊中也有一個AND。 也許您可以跳過其中一些OR,例如“ initials”(但這當然是一個很瘋狂的猜測……)

暫無
暫無

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

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