So, I'm back to being stuck on this.
I have inserted 500,000 random urls (no extra lookups - still just
1000), and now the query (as per the below reply) is back to being
somewhat slow (I'm using sqlite 3.15) at about 0.6s per request.
After a couple of hours of investigation, it's only slow when there is
either no ORDER BY, or if I use DESC (which is what I need). If I use
ORDER BY u.url ASC - it's near instantaneous.
I've tried every possible combination of indexes I can think up,
including of course with url_id DESC. I've also removed the ORDER BY in
the view (and set it to DESC as well), but that made absolutely no
difference.
I'm a little confused as to why I'm seeing this behaviour - my limited
understanding of the query-planner and reading
https://sqlite.org/queryplanner.html - suggests that at least when using
indexes, it'll simply scan an index backwards if that looks like it'll
help. I appreciate this is a result-set not an index, but in this case
could not the query planner realise that reading through the results
backwards would be faster than whatever it's doing?
And for that matter, shouldn't no ORDER BY be at least the same speed as
ORDER BY u.url_id ASC?
Thoughts welcome; Thanks!
Jonathan
On 2018-03-19 00:24, Jonathan Moules wrote:
Thanks Simon and Quan.
I'm not sure it's the view itself per-se - It takes 0.000s (time too
small to measure) for just the full View to be run on this dataset.
It turns out the problem is simpler than that and no data changes are
needed. I did consider Quan Yong Zhai's option and gave it a try, but
couldn't fathom out the necessary SQL to get what I wanted (it's
getting late).
Instead prompted by the replies here, I've changed the query very
slightly to the below which solves the problem:
SELECT
u.url, l.error_code
FROM
urls u
LEFT JOIN
lookups l
USING(url_id)
LEFT JOIN
(select * from v_most_recent_lookup_per_url where url_id in (
select url_id from urls where url = 'example.com'
)) recent
-- By definition url's can) recent
-- This is the important bit
-- Here we use the most recent lookup url_id to link to the
source_seed_id, so we only find its children
-- Or alternatively itself
ON u.source_seed_id = recent.url_id
OR u.url_id = recent.url_id
WHERE
-- For JSON-spider at least, Generic's are guaranteed to be
generic pages.
l.is_generic_flag = 1
AND
-- Must be "or equal to" so we can get the lookup of the very
base url.
l.retrieval_datetime >= recent.retrieval_datetime
AND
DATETIME(recent.retrieval_datetime) > DATETIME('now', '-5 days')
ORDER BY
u.url_id DESC
LIMIT 1;
To save readers having to compare manually, the difference is this: I
turned the "recent" alias item from the View into a subquery (still
using the view), and then moved the "where url = example.com" part in
to there.
The query is now literally two orders of magnitude faster, from 0.2s
to 0.004s. No new indexes or anything, just that change.
Hopefully this will scale to full datasets; if it doesn't I may have
to consider the other suggestions, but for now this is a
minimum-effort solution.
I'm not actually sure what SQLite was doing in the previous query to
make it take so long. , so I imagine there was some hideous recursing
going on or something.
Scope for optimisation?
Thanks again,
Jonathan
_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users