Hello everybody,
We use OJS 3.2.1.3 since 2 years with mysql 5.5 and PHP 7.3.
We host 10 journals.
Recently, we encountered a display problem with the authors’ page (/search/authors → searchAuthorIndex.tpl) for several journals which have lot of submissions and authors.
The page can’t stop running and never displayed.
I tested the SQL query that is generated and I found that the problem comes from the query conditions.
It’s a similar problem that I had already reported in october 2020 :
https://forum.pkp.sfu.ca/t/search-is-slow-and-not-always-working-after-upgrade-to-ojs-3-2-1-1/
The basic query is as follows (with the famous CAST condition in bold) and for some journals query runs for ever and never ends:
Query 1: SELECT a.*, ug.show_title, s.locale, COALESCE(agl.setting_value, agpl.setting_value) AS author_given, CASE WHEN agl.setting_value <> ‘’ THEN afl.setting_value ELSE afpl.setting_value END AS author_family FROM authors a JOIN user_groups ug ON (a.user_group_id = ug.user_group_id) JOIN publications p ON (p.publication_id = a.publication_id) JOIN submissions s ON (s.current_publication_id = p.publication_id) LEFT JOIN author_settings agl ON (a.author_id = agl.author_id AND agl.setting_name = ‘givenName’ AND agl.locale = ‘en_US’) LEFT JOIN author_settings agpl ON (a.author_id = agpl.author_id AND agpl.setting_name = ‘givenName’ AND agpl.locale = s.locale) LEFT JOIN author_settings afl ON (a.author_id = afl.author_id AND afl.setting_name = ‘familyName’ AND afl.locale = ‘en_US’) LEFT JOIN author_settings afpl ON (a.author_id = afpl.author_id AND afpl.setting_name = ‘familyName’ AND afpl.locale = s.locale) JOIN ( SELECT MIN(aa.author_id) as author_id, CONCAT( ac.setting_value, ’ ’ , COALESCE(asg0.setting_value, ‘’), ’ ', COALESCE(asf0.setting_value, ‘’), ’ ', COALESCE(SUBSTRING(asa0.setting_value FROM 1 FOR 255), ‘’), ’ ’ ) as names FROM authors aa JOIN publications pp ON (pp.publication_id = aa.publication_id) LEFT JOIN publication_settings ppss ON (ppss.publication_id = pp.publication_id) JOIN submissions ss ON (ss.submission_id = pp.submission_id AND ss.current_publication_id = pp.publication_id AND ss.status = 3) JOIN journals j ON (ss.context_id = j.journal_id) JOIN issues i ON (ppss.setting_name = ‘issueId’ AND ppss.setting_value = CAST(i.issue_id AS CHAR(20)) AND i.published = 1) LEFT JOIN author_settings ac ON (ac.author_id = aa.author_id AND ac.setting_name = ‘country’) LEFT JOIN author_settings asg0 ON (asg0.author_id = aa.author_id AND asg0.setting_name = ‘givenName’ AND asg0.locale = ‘en_US’) LEFT JOIN author_settings asf0 ON (asf0.author_id = aa.author_id AND asf0.setting_name = ‘familyName’ AND asf0.locale = ‘en_US’) LEFT JOIN author_settings asa0 ON (asa0.author_id = aa.author_id AND asa0.setting_name = ‘affiliation’ AND asa0.locale = ‘en_US’) WHERE j.enabled = 1 AND j.journal_id = 1 GROUP BY names ) as t1 ON (t1.author_id = a.author_id) ORDER BY author_family, author_given;
I added 3 conditions (in bold) to optimize the query to make it working again and running in an acceptable time:
Query 2: SELECT a.*, ug.show_title, s.locale, COALESCE(agl.setting_value, agpl.setting_value) AS author_given, CASE WHEN agl.setting_value <> ‘’ THEN afl.setting_value ELSE afpl.setting_value END AS author_family FROM authors a JOIN user_groups ug ON (a.user_group_id = ug.user_group_id) JOIN publications p ON (p.publication_id = a.publication_id) JOIN submissions s ON (s.current_publication_id = p.publication_id) LEFT JOIN author_settings agl ON (a.author_id = agl.author_id AND agl.setting_name = ‘givenName’ AND agl.locale = ‘en_US’) LEFT JOIN author_settings agpl ON (a.author_id = agpl.author_id AND agpl.setting_name = ‘givenName’ AND agpl.locale = s.locale) LEFT JOIN author_settings afl ON (a.author_id = afl.author_id AND afl.setting_name = ‘familyName’ AND afl.locale = ‘en_US’) LEFT JOIN author_settings afpl ON (a.author_id = afpl.author_id AND afpl.setting_name = ‘familyName’ AND afpl.locale = s.locale) JOIN ( SELECT MIN(aa.author_id) as author_id, CONCAT( ac.setting_value, ’ ’ , COALESCE(asg0.setting_value, ‘’), ’ ', COALESCE(asf0.setting_value, ‘’), ’ ', COALESCE(SUBSTRING(asa0.setting_value FROM 1 FOR 255), ‘’), ’ ’ ) as names FROM authors aa JOIN publications pp ON (pp.publication_id = aa.publication_id) LEFT JOIN publication_settings ppss ON (ppss.publication_id = pp.publication_id ) JOIN submissions ss ON (ss.submission_id = pp.submission_id AND ss.current_publication_id = pp.publication_id AND ss.status = 3) JOIN journals j ON (ss.context_id = j.journal_id) JOIN issues i ON (ppss.setting_name = ‘issueId’ AND ppss.setting_value = CAST(i.issue_id AS CHAR(20)) AND i.published = 1 AND ppss.locale =‘’ AND ss.context_id = i.journal_id) LEFT JOIN author_settings ac ON (ac.author_id = aa.author_id AND ac.setting_name = ‘country’ AND ac.locale = ‘’) LEFT JOIN author_settings asg0 ON (asg0.author_id = aa.author_id AND asg0.setting_name = ‘givenName’ AND asg0.locale = ‘en_US’) LEFT JOIN author_settings asf0 ON (asf0.author_id = aa.author_id AND asf0.setting_name = ‘familyName’ AND asf0.locale = ‘en_US’) LEFT JOIN author_settings asa0 ON (asa0.author_id = aa.author_id AND asa0.setting_name = ‘affiliation’ AND asa0.locale = ‘en_US’) WHERE j.enabled = 1 AND j.journal_id = 1 GROUP BY names ) as t1 ON (t1.author_id = a.author_id) ORDER BY author_family, author_given;
But where the query is the fastest is when I only replace in original query:
Query 3:
AND ppss.setting_value = CAST(i.issue_id AS CHAR(20))
with
AND CAST(ppss.setting_value AS UNSIGNED) = i.issue_id
I know you have to create a query which works with both DB Mysql and PostgreSQL and that PostgreSQL doesn’t like to implicitly convert between strings and numbers.
Could you plan to change the query to make it working again : either query 2 or either (idealy for us) query 3 ?
Thanks in advance.
Best regards.
Helene