9

我们的一个网站上有一个搜索引擎,速度非常慢。我打开了慢查询日志并记录了所有耗时超过 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 秒。

我对同一个查询做了一个解释,而 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 上要慢得多?或者更重要的是,有没有办法让这个网站上的查询更快?

如果您需要更多信息进行故障排除,请大声疾呼,我会尽力提供。

提前非常感谢,简。

这是查询的简介:

+----------------------+----------+
| 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 |
+----------------------+----------+
4

2 回答 2

2

我看到很多不可索引的条件,例如Firstname LIKE '%statutair%'. 一种可能是 MySQL 实际上正在使用其结果缓存,而 PHP 无法利用结果缓存。例如,如果您使用带有ATTR_EMULATE_PREPARES 选项 disabled的 PDO,就会发生这种情况。

要找出答案,请在 MySQL 中进行测试时添加 SQL_NO_CACHE 子句,如下所示:

SELECT SQL_NO_CACHE id, name FROM customer;
于 2012-08-01T10:18:33.980 回答
0

在我看来,您必须在很多列上设置索引。请阅读:http ://dev.mysql.com/doc/refman/5.0/en/explain-output.html 为了使查询更快,首先为您在 JOIN 语句中使用的每一列设置一个索引。如果这不能加快速度,请在您检查 WHERE 的列上设置索引。此外,OR 运算符很慢,在所有 OR 的块中还有一个 AND。也许您可以跳过其中的一些 OR,例如“姓名首字母”(但这当然是一个疯狂的猜测……)

于 2012-08-01T16:24:58.140 回答