php - 在 MySQL 中查询速度快,但在 PHP 中查询速度慢

标签 php mysql

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

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 中慢得多?或者更重要的是,有没有办法让这个网站上的查询更快?

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

非常感谢, 一月

这是查询的 PROFILE:

+----------------------+----------+
| 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 实际上正在使用它的 results cache ,而 PHP 无法利用结果缓存。这可能会发生,例如,如果您将 PDO 与 ATTR_EMULATE_PREPARES option disabled 一起使用.

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

SELECT SQL_NO_CACHE id, name FROM customer;

关于php - 在 MySQL 中查询速度快,但在 PHP 中查询速度慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11756932/

相关文章:

php - 如何检查表中是否存在元素(mysql)

javascript - 从 php json 解码中检索 json 数组

php - 单击复选框时如何添加新内容?

java - JPA EntityManager 和字符编码

php - 如何提取表单的隐藏值并将其插入数据库

javascript - 计算 epub 的总页数

php - “字段列表”中的未知列“xxx”

php - 超过 600 个连接的 MySQL

php - 在使用 jQuery $.ajax PHP/MySQL 插入后添加表行

php - 如何将生成的字母数字字符串存储到数据库 phpmyadmin