Closed danimo closed 1 year ago
Slow query log analysis (note the insane amount of thousands of request querying for the value 'S' in all possible and impossible fields):
%mysqldumpslow
Reading mysql slow query log from /var/log/mysql/slow-query.log
Count: 1 Time=0.01s (0s) Lock=0.00s (0s) Rows_sent=5367.0 (5367), Rows_examined=5367.0 (5367), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT * FROM wp_podlove_modules_logging_logtable WHERE time > N
Count: 1 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=3495.0 (3495), Rows_examined=6928.0 (6928), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT post_id, meta_key, meta_value FROM wp_postmeta WHERE post_id IN (N,,{repeated 238 times}N) ORDER BY meta_id ASC
Count: 1 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=1833.0 (1833), Rows_examined=6928.0 (6928), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT post_id, meta_key, meta_value FROM wp_postmeta WHERE post_id IN (N,,{repeated 140 times}N) ORDER BY meta_id ASC
Count: 1 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=1675.0 (1675), Rows_examined=6928.0 (6928), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT post_id, meta_key, meta_value FROM wp_postmeta WHERE post_id IN (N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N) ORDER BY meta_id ASC
Count: 1 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=240.0 (240), Rows_examined=968.0 (968), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT
e.*
FROM
wp_podlove_episode e
INNER JOIN wp_posts p ON e.post_id = p.ID
WHERE
N = N AND p.post_status = 'S'
AND p.post_type = "S"
ORDER BY p.post_date DESC
Count: 1 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=240.0 (240), Rows_examined=968.0 (968), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT
e.*
FROM
`wp_podlove_episode` e
JOIN `wp_posts` p ON e.post_id = p.ID
WHERE
p.post_status IN ("S", "S", "S", "S", "S")
AND
p.post_type = "S"
ORDER BY
p.post_date DESC
Count: 1 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=478.0 (478), Rows_examined=2168.0 (2168), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT t.*, tt.*, tr.object_id FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON t.term_id = tt.term_id INNER JOIN wp_term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ('S', 'S') AND tr.object_id IN (N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N) ORDER BY t.name ASC
Count: 1 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=282.0 (282), Rows_examined=1776.0 (1776), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT t.*, tt.*, tr.object_id FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON t.term_id = tt.term_id INNER JOIN wp_term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ('S', 'S') AND tr.object_id IN (N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N) ORDER BY t.name ASC
Count: 1 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=198.0 (198), Rows_examined=1608.0 (1608), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT t.*, tt.*, tr.object_id FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON t.term_id = tt.term_id INNER JOIN wp_term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ('S', 'S') AND tr.object_id IN (N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N) ORDER BY t.name ASC
Count: 240 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=1.0 (240), Rows_examined=729.0 (174960), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT
e.*
FROM
`wp_podlove_episode` e
JOIN `wp_posts` p ON e.post_id = p.ID
WHERE
p.post_type = 'S' AND
p.post_status = 'S'
ORDER BY
p.post_date ASC
LIMIT N,N
Count: 240 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=1.0 (240), Rows_examined=729.0 (174960), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT
e.*
FROM
`wp_podlove_episode` e
JOIN `wp_posts` p ON e.post_id = p.ID
WHERE
p.post_type = 'S' AND
p.post_status = 'S'
ORDER BY
p.post_date DESC
LIMIT N,N
Count: 1 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=720.0 (720), Rows_examined=1208.0 (1208), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT
p.post_status,
mf.episode_id,
mf.episode_asset_id,
mf.size,
mf.id media_file_id
FROM
`wp_podlove_mediafile` mf
JOIN `wp_podlove_episode` e ON e.id = mf.`episode_id`
JOIN `wp_posts` p ON e.`post_id` = p.`ID`
WHERE
p.`post_type` = 'S'
AND p.post_status in ('S', 'S', 'S', 'S', 'S')
Count: 7 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=2.0 (14), Rows_examined=3190.0 (22330), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT comment_approved, COUNT( * ) AS total
FROM wp_comments
GROUP BY comment_approved
Count: 5760 Time=0.00s (6s) Lock=0.00s (0s) Rows_sent=1.0 (5520), Rows_examined=614.1 (3537120), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT
e.*
FROM
`wp_podlove_episode` e
JOIN `wp_posts` p ON e.post_id = p.ID
WHERE
p.post_type = 'S' AND
p.post_status = 'S'
AND DATE(p.post_date) > 'S'
ORDER BY
p.post_date ASC
LIMIT N,N
Count: 11520 Time=0.00s (12s) Lock=0.00s (0s) Rows_sent=1.0 (11040), Rows_examined=603.8 (6956160), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT
e.*
FROM
`wp_podlove_episode` e
JOIN `wp_posts` p ON e.post_id = p.ID
WHERE
p.post_type = 'S' AND
p.post_status = 'S'
AND DATE(p.post_date) < 'S'
ORDER BY
p.post_date DESC
LIMIT N,N
Count: 1 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=2.0 (2), Rows_examined=8.0 (8), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT DISTINCT p.*, e.post_id, i.id AS instance_id, i.start AS start, i.end AS end, e.allday AS event_allday, e.recurrence_rules, e.exception_rules, e.ticket_url, e.instant_event, e.recurrence_dates, e.exception_dates, e.venue, e.country, e.address, e.city, e.province, e.postal_code, e.show_map, e.contact_name, e.contact_phone, e.contact_email, e.cost, e.ical_feed_url, e.ical_source_url, e.ical_organizer, e.ical_contact, e.ical_uid, e.timezone_name, e.longitude, e.latitude FROM wp_ai1ec_events e INNER JOIN wp_posts p ON e.post_id = p.ID INNER JOIN wp_ai1ec_event_instances i ON e.post_id = i.post_id WHERE post_type = 'S' AND i.end >= N AND post_status = 'S' ORDER BY i.start ASC, post_title ASC LIMIT N, N
Count: 3 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=606.0 (1818), Rows_examined=606.0 (1818), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT * FROM wp_podlove_job
Count: 1 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=2.0 (2), Rows_examined=8.0 (8), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT DISTINCT p.*, e.post_id, i.id AS instance_id, i.start AS start, i.end AS end, e.allday AS event_allday, e.recurrence_rules, e.exception_rules, e.ticket_url, e.instant_event, e.recurrence_dates, e.exception_dates, e.venue, e.country, e.address, e.city, e.province, e.postal_code, e.show_map, e.contact_name, e.contact_phone, e.contact_email, e.cost, e.ical_feed_url, e.ical_source_url, e.ical_organizer, e.ical_contact, e.ical_uid, e.timezone_name, e.longitude, e.latitude FROM wp_ai1ec_events e INNER JOIN wp_posts p ON e.post_id = p.ID INNER JOIN wp_ai1ec_event_instances i ON e.post_id = i.post_id WHERE post_type = 'S' AND i.end >= N AND post_status IN ( 'S', 'S' ) ORDER BY i.start ASC, post_title ASC LIMIT N, N
Count: 41 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=224.2 (9192), Rows_examined=1238.2 (50766), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT option_name, option_value FROM wp_options WHERE autoload = 'S'
Count: 36 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=0.0 (0), Rows_examined=606.0 (21816), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT
*
FROM
wp_podlove_job j
WHERE `class` LIKE "S" AND steps_total > steps_progress
ORDER BY `updated_at` DESC
LIMIT N,N
Count: 18 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=0.0 (0), Rows_examined=606.0 (10908), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT
*
FROM
wp_podlove_job j
WHERE `class` LIKE "S" AND steps_total <= steps_progress
ORDER BY `updated_at` DESC
LIMIT N,N
Count: 6 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=1.0 (6), Rows_examined=607.0 (3642), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT
*
FROM
wp_podlove_job j
WHERE `class` LIKE "S"
ORDER BY `updated_at` DESC
LIMIT N,N
Count: 5 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=0.0 (0), Rows_examined=606.0 (3030), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT
*
FROM
wp_podlove_job
WHERE
steps_total > steps_progress
ORDER BY created_at ASC
LIMIT N, N
Count: 1 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=45.0 (45), Rows_examined=180.0 (180), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT
ec.id, ec.role_id, ec.group_id,
(case when c.gender = 'S' then N else N end) AS male,
(case when c.gender = 'S' then N else N end) AS female,
(case when c.gender NOT IN ('S', 'S') then N else N end) AS notattributed
FROM
`wp_podlove_modules_contributors_episodecontribution` ec
JOIN `wp_podlove_episode` e ON e.id = ec.episode_id
JOIN `wp_posts` p ON p.ID = e.`post_id` AND p.post_status IN ('S', 'S')
JOIN `wp_podlove_modules_contributors_contributor` c ON ec.`contributor_id` = c.id
Count: 1 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=1.0 (1), Rows_examined=1.0 (1), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT * FROM `TABLES` WHERE `TABLE_SCHEMA` = 'S' AND `TABLE_NAME` = 'S'
Count: 2 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=3.0 (6), Rows_examined=12.0 (24), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT
f.*
FROM
wp_podlove_feed f
JOIN wp_podlove_episodeasset a ON a.id = f.episode_asset_id
JOIN wp_podlove_filetype ft ON ft.id = a.file_type_id
WHERE
f.slug IS NOT NULL AND f.discoverable
ORDER BY
position ASC
Count: 240 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=3.0 (720), Rows_examined=9.0 (2160), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT M.*
FROM wp_podlove_mediafile M
JOIN wp_podlove_episodeasset A ON A.id = M.episode_asset_id
WHERE M.episode_id = 'S'
ORDER BY A.position ASC
Count: 240 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=0.0 (0), Rows_examined=25.0 (6000), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT * FROM wp_podlove_modules_seasons_season WHERE start_date < 'S' OR start_date IS NULL AND id != N
Count: 6000 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=1.0 (5760), Rows_examined=26.0 (155760), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT * FROM wp_podlove_modules_seasons_season WHERE
start_date < 'S'
OR start_date IS NULL
ORDER BY
start_date DESC LIMIT N,N
Count: 42 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=3.0 (126), Rows_examined=3.0 (126), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT * FROM wp_podlove_feed
Count: 1 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=3.0 (3), Rows_examined=3.0 (3), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT * FROM wp_podlove_feed WHERE discoverable = 'S'
Count: 20283 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=1.0 (20043), Rows_examined=26.0 (527118), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT * FROM wp_podlove_modules_seasons_season WHERE start_date > 'S' ORDER BY start_date ASC LIMIT N,N
Count: 240 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=25.0 (6000), Rows_examined=25.0 (6000), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT * FROM wp_podlove_modules_seasons_season
Count: 5 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=1.0 (5), Rows_examined=2.0 (10), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT * FROM wp_podlove_feed WHERE slug = 'S' LIMIT N,N
Count: 2 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=3.0 (6), Rows_examined=3.0 (6), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT * FROM wp_podlove_episodeasset
Count: 1 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=1.0 (1), Rows_examined=45.0 (45), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT COUNT(*) FROM wp_podlove_modules_contributors_episodecontribution
Count: 1 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=2.0 (2), Rows_examined=2.0 (2), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT * FROM wp_podlove_template
Count: 1 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=5.0 (5), Rows_examined=5.0 (5), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT * FROM wp_podlove_modules_contributors_showcontribution
Count: 965 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=1.0 (965), Rows_examined=1.0 (965), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT * FROM wp_podlove_template WHERE title = 'S' LIMIT N,N
Count: 6 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=0.0 (0), Rows_examined=0.0 (0), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT `feed_id` FROM `wp_ai1ec_event_feeds`
Count: 274 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=3.0 (822), Rows_examined=3.0 (822), Rows_affected=0.0 (0), wordpress[wordpress]@localhost
SELECT slug FROM wp_podlove_feed
Count: 1 Time=0.00s (0s) Lock=0.00s (0s) Rows_sent=0.0 (0), Rows_examined=0.0 (0), Rows_affected=0.0 (0), 0users@0hosts
# Time: N N:N:N
# User@Host: wordpress[wordpress] @ localhost []
# Thread_id: N Schema: chaosradio QC_hit: No
# Query_time: N.N Lock_time: N.N Rows_sent: N Rows_examined: N
# Rows_affected: N Bytes_sent: N
SET timestamp=N;
SELECT option_name, option_value FROM wp_options WHERE autoload = 'S'
It seems the seasons module produces excessive/expensive queries on feed generation. In my quick tests it increased feed generation time dramatically.
In general the feed generation could use a rewrite. Data can and should be queried much more efficiently.
That being said, 26 seconds seems excessive, even for a feed with hundreds of episodes. In my tests just now I used a podcast with 220 episodes and it renders in about 5 seconds.
And I cannot make heads or tails about the queries for S
. Or is that just the way of the query logger to mark common queries with different values?
Is there a way to more console/log file debugging somewhere for the RSS generator?
The N/S variables are a substitution of mysqldumpslow I think.
I like to use https://wordpress.org/plugins/query-monitor/ for basic performance stuff but unfortunately that relies on a web UI and is not usable for RSS as far as I know. So I do it manually.
# wp-config.php
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('SAVEQUERIES', true);
At the end of <publisher-plugin>/templates/feed-rss2.php
:
</rss>
<?php
global $wpdb;
$sum = 0;
foreach ($wpdb->queries as $query) {
$sum += $query[1];
error_log(print_r($query[0] . " in " . $query[1] . "\n\n", true));
}
error_log(print_r(count($wpdb->queries) . " queries in " . $sum, true));
Then all queries and their times are logged in wp-content/debug.log
. Requires a bunch of PHP memory though as SAVEQUERIES
keeps a lot of metadata.
Do you want me to run this? alternative, I can grant you temporary access or offer a backup for offline debugging purposes.
You don't need to, I am pretty sure I know where I need to optimize. It also serves as a note to myself ;)
This https://github.com/podlove/podlove-publisher/blob/master/lib/modules/seasons/model/season.php#L16 is really expensive and run for every episode in the feed. Shouldn't be too hard to optimize at least that section.
Hey Eric, do you have an ETA for a patch? Not trying to be pushy, just checking if I need to deploy a special caching strategy for the feeds before the relaunch. Let me know if I can help.
I have a patch ready that should help a lot. Just needs some more testing that I didn't break anything. Should be released within the next few days.
I also have some plans of rewriting the whole feed generation for another big performance gain but that will take more time.
Since the feed is one of the notable podcast hosting bottlenecks, caching is still not a bad idea. Only with some manual effort you can prevent feed requests to go through PHP/WordPress.
An idea:
I am currently using the fastcgi_cache mechanism to cache all assets, but only for a limited time (it gets purged by a WP plugin once related things in WP change). I would probably need to remove time timeout in this case. Cronjob sounds like a good idea as well.
Forgot to reference the issue in the commit message: https://github.com/podlove/podlove-publisher/commit/ad5f9138a5bb0bdb3de3a0eefc74721865750d17
Wow, this brought down rendering time to ~1sec.
Expected behavior
First (uncached)
GET
on feed URLs (like/feed/m4a
) return almost immediatelyActual behavior
The
GET
request takes 26 secondsSystem information (see
Podlove > Support
menu)