2012-08-01 24 views
6

Tenemos un motor de búsqueda en uno de nuestros sitios web que es extremadamente lento. Active el registro lento de consultas y registre todas las consultas que tarden más de 10 segundos. Solo se registran las consultas de este motor de búsqueda. Aquí es un ejemplo del registro:Consulta rápida en MySQL pero lenta en PHP

# Time: 120801 9:21:42 
# [email protected]: ********** @ 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; 

Como se puede ver la consulta tardó aproximadamente 22 segundos en ejecutarse, si hacer la misma consulta directamente en MySQL se tarda aproximadamente 4 segundos.

hice un explique en esta misma consulta y la uotput es el siguiente:

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                  

¿Alguien podría explicar por qué la misma consulta es taaan mucho más lento en mi sitio web a continuación, dirigir en MySQL? O, lo que es más importante, ¿hay alguna forma de hacer esta consulta más rápido en este sitio web?

Si necesita más información para solucionar problemas, dé un grito e intentaré proporcionarlos.

Muchas gracias de antemano, Jan.

Este es el perfil de la consulta:

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

* Madre de Dios ... * – MacMac

+1

Bienvenido a SO, felicidades por un muy bien presentado primera pregunta :) – Dale

+3

Si los datos que se transmiten son significativos, llevará tiempo devolverlos a su aplicación php. En serio, recomendaría configurar un sqlfiddle con esta pregunta ya que su consulta es enorme y difícil de analizar sin verlo en acción (o al menos para mí lo es) – Lee

Respuesta

0

Me parece que usted tiene que fijar un índice en una gran cantidad de columnas. Lea esto: http://dev.mysql.com/doc/refman/5.0/en/explain-output.html Para que la consulta sea más rápida, comience por establecer un índice en cada columna que use en sus instrucciones JOIN. Si eso no acelera las cosas, establezca un índice en las columnas donde verifique su DONDE está en contra. Además, el operador OR es lento, y en el bloque con todos los OR también hay un AND. Y tal vez puede omitir algunos de esos OR, como 'iniciales' (pero eso es, por supuesto, una suposición descabellada ...)

2

veo un montón de condiciones no indexables como Firstname LIKE '%statutair%'. Una posibilidad es que MySQL esté utilizando su results cache, mientras que PHP no puede aprovechar la caché de resultados. Esto puede suceder, por ejemplo, si usa PDO con el ATTR_EMULATE_PREPARES option disabled.

Para saberlo, añadir la cláusula SQL_NO_CACHE cuando se prueba desde dentro de MySQL, como en:

SELECT SQL_NO_CACHE id, name FROM customer; 
+0

Hola Álvaro. Los 4s mencionados que dí fueron un resultado no almacenado en caché. Si vuelvo a consultar en MySQL, los resultados aparecen en aproximadamente 30 ms. El sitio web parece estar en caché también.Si utilizo la misma palabra de búsqueda de nuevo, los resultados llegan bastante rápido en la pantalla. – Jan

+0

@Jan - Bueno, fue solo un tiro en la oscuridad :) –

+0

¡Y eso es apreciado, por supuesto! :) – Jan

Cuestiones relacionadas