[wp-trac] [WordPress Trac] #18536: Improve performance of WP_Query core

WordPress Trac wp-trac at lists.automattic.com
Mon Aug 29 00:50:41 UTC 2011


#18536: Improve performance of WP_Query core
-------------------------+------------------------------
 Reporter:  cheald       |       Owner:
     Type:  enhancement  |      Status:  new
 Priority:  normal       |   Milestone:  Awaiting Review
Component:  Query        |     Version:  3.2.1
 Severity:  normal       |  Resolution:
 Keywords:  has-patch    |
-------------------------+------------------------------

Comment (by cheald):

 The problem is indeed the tablesorts. This patch helps keep our queries
 out of tablesort territory by reducing the amount of data that the DB has
 to chew on. Here's a chunk from our slow query log:


 {{{
 # User at Host: prod[prod] @  [192.168.100.162]
 # Thread_id: 213317196  Schema: prod  Last_errno: 0  Killed: 0
 # Query_time: 0.542673  Lock_time: 0.000094  Rows_sent: 2  Rows_examined:
 47995  Rows_affected: 0  Rows_read: 9108
 # Bytes_sent: 10754  Tmp_tables: 1  Tmp_disk_tables: 1  Tmp_table_sizes:
 50918492
 # InnoDB_trx_id: 676FA764
 # QC_Hit: No  Full_scan: No  Full_join: No  Tmp_table: Yes
 Tmp_table_on_disk: Yes
 # Filesort: Yes  Filesort_on_disk: No  Merge_passes: 0
 #   InnoDB_IO_r_ops: 0  InnoDB_IO_r_bytes: 0  InnoDB_IO_r_wait: 0.000000
 #   InnoDB_rec_lock_wait: 0.000000  InnoDB_queue_wait: 0.000000
 #   InnoDB_pages_distinct: 10030
 SET timestamp=1302277759;
 SELECT SQL_CALC_FOUND_ROWS  wp_posts.* FROM wp_posts  INNER JOIN
 wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)
 INNER JOIN wp_term_taxonomy ON (wp_term_relationships.term_taxonomy_id =
 wp_term_taxonomy.term_taxonomy_id)  WHERE 1=1  AND wp_posts.ID NOT IN
 (332000,583467,583371,579313,583657,583185) AND wp_term_taxonomy.taxonomy
 = 'post_tag'  AND wp_term_taxonomy.term_id IN ('1862', '82', '19567',
 '553', '135', '43', '1174', '1100', '5819', '16796', '119', '74')  AND
 wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish') GROUP
 BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 2;
 }}}

 And here's the EXPLAIN:

 {{{
 +----+-------------+-----------------------+--------+--------------------------------------+------------------+---------+----------------------------------------+------+-----------------------------------------------------------+
 | id | select_type | table                 | type   | possible_keys
 | key              | key_len | ref                                    |
 rows | Extra                                                     |
 +----+-------------+-----------------------+--------+--------------------------------------+------------------+---------+----------------------------------------+------+-----------------------------------------------------------+
 |  1 | SIMPLE      | wp_term_taxonomy      | range  |
 PRIMARY,term_id_taxonomy,taxonomy    | term_id_taxonomy | 106     | NULL
 |   12 | Using where; Using index; Using temporary; Using filesort |
 |  1 | SIMPLE      | wp_term_relationships | ref    |
 PRIMARY,term_taxonomy_id             | term_taxonomy_id | 8       |
 prod.wp_term_taxonomy.term_taxonomy_id |   15 | Using index
 |
 |  1 | SIMPLE      | wp_posts              | eq_ref |
 PRIMARY,post_status,type_status_date | PRIMARY          | 8       |
 prod.wp_term_relationships.object_id   |    1 | Using where
 |
 +----+-------------+-----------------------+--------+--------------------------------------+------------------+---------+----------------------------------------+------+-----------------------------------------------------------+
 }}}

 Nothing too fancy going on there,
 The really interesting thing there is the temp table size - 50,918,492
 bytes - just to get 2 posts! "Tmp_table_on_disk" explains the performance
 pretty easily - making the context switch to write the temp table isn't
 trivial!

 Here's another:

 {{{

 # User at Host: prod[prod] @  [192.168.100.162]
 # Thread_id: 213303997  Schema: prod  Last_errno: 0  Killed: 0
 # Query_time: 0.909574  Lock_time: 0.000117  Rows_sent: 2  Rows_examined:
 33733  Rows_affected: 0  Rows_read: 6785
 # Bytes_sent: 11761  Tmp_tables: 1  Tmp_disk_tables: 1  Tmp_table_sizes:
 40452708
 # InnoDB_trx_id: 676ED8D4
 # QC_Hit: No  Full_scan: No  Full_join: No  Tmp_table: Yes
 Tmp_table_on_disk: Yes
 # Filesort: Yes  Filesort_on_disk: No  Merge_passes: 0
 #   InnoDB_IO_r_ops: 0  InnoDB_IO_r_bytes: 0  InnoDB_IO_r_wait: 0.000000
 #   InnoDB_rec_lock_wait: 0.000000  InnoDB_queue_wait: 0.000000
 #   InnoDB_pages_distinct: 7863
 SET timestamp=1302277444;
 SELECT SQL_CALC_FOUND_ROWS  wp_posts.* FROM wp_posts  INNER JOIN
 wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)
 INNER JOIN wp_term_taxonomy ON (wp_term_relationships.term_taxonomy_id =
 wp_term_taxonomy.term_taxonomy_id)  WHERE 1=1  AND wp_posts.ID NOT IN
 (249519,583467,583371,579313,583657,583185) AND wp_term_taxonomy.taxonomy
 = 'post_tag'  AND wp_term_taxonomy.term_id IN ('20747', '2009', '82',
 '131', '553', '135', '1156', '732', '1100', '119')  AND wp_posts.post_type
 = 'post' AND (wp_posts.post_status = 'publish') GROUP BY wp_posts.ID ORDER
 BY wp_posts.post_date DESC LIMIT 0, 2;
 }}}

 Explained:

 {{{

 +----+-------------+-----------------------+--------+--------------------------------------+------------------+---------+----------------------------------------+------+-----------------------------------------------------------+
 | id | select_type | table                 | type   | possible_keys
 | key              | key_len | ref                                    |
 rows | Extra                                                     |
 +----+-------------+-----------------------+--------+--------------------------------------+------------------+---------+----------------------------------------+------+-----------------------------------------------------------+
 |  1 | SIMPLE      | wp_term_taxonomy      | range  |
 PRIMARY,term_id_taxonomy,taxonomy    | term_id_taxonomy | 106     | NULL
 |   10 | Using where; Using index; Using temporary; Using filesort |
 |  1 | SIMPLE      | wp_term_relationships | ref    |
 PRIMARY,term_taxonomy_id             | term_taxonomy_id | 8       |
 prod.wp_term_taxonomy.term_taxonomy_id |   15 | Using where; Using index
 |
 |  1 | SIMPLE      | wp_posts              | eq_ref |
 PRIMARY,post_status,type_status_date | PRIMARY          | 8       |
 prod.wp_term_relationships.object_id   |    1 | Using where
 |
 +----+-------------+-----------------------+--------+--------------------------------------+------------------+---------+----------------------------------------+------+-----------------------------------------------------------+
 }}}

 All the patch does is reduce the amount of data that MySQL has to manage
 to perform the sort - with small dataset sizes, this isn't likely to have
 much of an impact, but once the size of your potential resultset (with
 included post content) passes your query into filesort territory, the
 differences become *big*.

-- 
Ticket URL: <http://core.trac.wordpress.org/ticket/18536#comment:2>
WordPress Trac <http://core.trac.wordpress.org/>
WordPress blogging software


More information about the wp-trac mailing list