Skip to content

Slow MySQL queries when reading new items #1282

Open
@albancrommer

Description

@albancrommer

My SELFOSS database has ~500 sources and ~330k items, the oldest from Jan 2016.

Love Selfoss thanks a lot for it !

Database Version : mariadb 10.3.27
PHP Version : PHP7.0  (yes, I know)
OS : Debian 11 Bullseye

My problem: SELFOSS keeps slowing down when loading items.

I have activated the MySQL Log, and the query executed on each items load is responsible.

Here is the main query :

SELECT
items.id, datetime, items.title AS title, content, unread, starred, source, thumbnail, icon, uid, link, updatetime, author, sources.title as sourcetitle, sources.tags as tagsitems.id, datetime, items.title AS title, content, unread, starred, source, thumbnail, icon, uid, link, updatetime, author, sources.title as sourcetitle, sources.tags as tags
FROM items AS items, sources AS sources
WHERE items.source=sources.id AND TRUE AND unread=1 
ORDER BY items.datetime DESC, items.id DESC 
LIMIT 50 OFFSET 0;
- - -
50 rows in set (6.440 sec)

Pretty slow.

Running the EXPLAIN plan for that query tells us more:

EXPLAIN SELECT 
items.id, datetime, items.title AS title, content, unread, starred, source, thumbnail, icon, uid, link, updatetime, author, sources.title as sourcetitle, sources.tags as tagsitems.id, datetime, items.title AS title, content, unread, starred, source, thumbnail, icon, uid, link, updatetime, author, sources.title as sourcetitle, sources.tags as tags
FROM items AS items, sources AS sources
WHERE items.source=sources.id AND TRUE AND unread=1 
ORDER BY items.datetime DESC, items.id DESC 
LIMIT 50 OFFSET 0;
+------+-------------+---------+------+---------------+--------+---------+--------------------------+------+---------------------------------+
| id   | select_type | table   | type | possible_keys | key    | key_len | ref                      | rows | Extra                           |
+------+-------------+---------+------+---------------+--------+---------+--------------------------+------+---------------------------------+
|    1 | SIMPLE      | sources | ALL  | PRIMARY       | NULL   | NULL    | NULL                     |  489 | Using temporary; Using filesort |
|    1 | SIMPLE      | items   | ref  | source        | source | 4       | alban_selfoss.sources.id |  349 | Using where                     |
+------+-------------+---------+------+---------------+--------+---------+--------------------------+------+---------------------------------+

The query shows use of temporary table and filesort, which is slow.

Let's see how ORDER BY clauses are responsible for that by removing them:

SELECT 
items.id, datetime, items.title AS title, content, unread, starred, source, thumbnail, icon, uid, link, updatetime, author, sources.title as sourcetitle, sources.tags as tags 
FROM items AS items, sources AS sources 
WHERE items.source=sources.id AND TRUE AND unread=1 
LIMIT 50 OFFSET 0;
- - - 
50 rows in set (0.001 sec)

EXPLAIN SELECT 
items.id, datetime, items.title AS title, content, unread, starred, source, thumbnail, icon, uid, link, updatetime, author, sources.title as sourcetitle, sources.tags as tags 
FROM items AS items, sources AS sources 
WHERE items.source=sources.id AND TRUE AND unread=1 
LIMIT 50 OFFSET 0;

+------+-------------+---------+------+---------------+--------+---------+--------------------------+------+-------------+
| id   | select_type | table   | type | possible_keys | key    | key_len | ref                      | rows | Extra       |
+------+-------------+---------+------+---------------+--------+---------+--------------------------+------+-------------+
|    1 | SIMPLE      | sources | ALL  | PRIMARY       | NULL   | NULL    | NULL                     |  489 |             |
|    1 | SIMPLE      | items   | ref  | source        | source | 4       | alban_selfoss.sources.id |  349 | Using where |
+------+-------------+---------+------+---------------+--------+---------+--------------------------+------+-------------+

Removing ORDER BY results in in 0.01 second query and no more temp table or filesort.

Solutions

It seems this is due to MySQL's handling of queries using ORDER BY cf. documentation.

A possible fix would be to split the query in 2 parts and let PHP associate items with sources.

SELECT
items.id, datetime, items.title AS title, content, unread, starred, source, thumbnail, icon, uid, link, updatetime, author
FROM items AS items
WHERE unread=1 
ORDER BY items.datetime DESC, items.id DESC 
LIMIT 50 OFFSET 0;
50 rows in set (0.001 sec)

SELECT sources.title as sourcetitle, sources.tags as tags
FROM sources AS sources;
489 rows in set (0.002 sec)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions