-
Notifications
You must be signed in to change notification settings - Fork 455
Description
Issue Description: I have found 2 issues which I believe are related. I have a large world ~15GB and use SQLite database as storage ~25GB which has over one million tiles.
1. Using internal webserver, accessing the map fails completely, the page loads a few components but then stalls, refreshing the page causes it load no data and time-out. Shutting down the server causes multiple SQLException errors.
2. When using a standalone webserver with the SQLite database, tiles load extremely slowly, around one tile a second or even slower when there are empty regions on the map.
I have conducted my own research on the slow retrieval of tiles using an sqlite database browser. I ran a similar sql command found in SQLite_tiles.php.
example:
SELECT Tiles.Image,Tiles.Format,Tiles.HashCode,Tiles.LastUpdate,Tiles.ImageLen
FROM Maps JOIN Tiles WHERE Maps.WorldID='world' AND Maps.MapID='t' AND Maps.Variant='STANDARD'
AND Maps.ID=Tiles.MapID AND Tiles.x=-1114826 AND Tiles.y=1123189 AND Tiles.zoom=0;
Execution finished without errors.
Result: 1 rows returned in 804ms
That takes nearly a second!
And for a tile that does not exist:
Result: 0 rows returned in 1971ms
That's 2 seconds!
So the database is getting severely bogged down looking for tiles whether or not they exist. The automatic Index feature of SQLite prevents databases operations from taking this long even on extremely large databases. However it seems to be not using it as shown below when debugging the request.
EXPLAIN QUERY PLAN ... (the select query above)
Result:
SCAN TABLE Tiles
SEARCH TABLE Maps USING INTEGER PRIMARY KEY (rowid=?)
Notice: "SCAN TABLE Tiles". Its not using the index on the table but scanning the entire table (over 1 million rows), when using a table JOIN in the query. I don't know if this is a SQLite driver bug or some other issue.
However, you can force it to use the index by preceding join with cross in the select statement.
Using the new query:
SELECT (...) FROM Maps CROSS JOIN Tiles WHERE Maps.WorldID=(...)
Result: 1 rows returned in 6ms
EXPLAIN QUERY PLAN ... (new query)
Result:
SCAN TABLE Maps
SEARCH TABLE Tiles USING INDEX sqlite_autoindex_Tiles_1 (MapID=? AND x=? AND y=? AND zoom=?)
Much better, it's using the index like it's supposed to...
See https://www.sqlite.org/optoverview.html#manual_control_of_query_plans_using_cross_join for more info on sqlite index.
Im not 100% sure but I think something similar is happening inside the dynmap plugin causing it to completely stall
This may also be the cause for issue #3434
This may possibly also affect mySQL database, although I have not tested this.
- Dynmap Version: dynmap v3.4-SNAPSHOT-768
- Server Version: paper 1.18.1 build git-Paper-216
- Pastebin of Configuration.txt: https://pastebin.com/Ne1HYuLE
- Server Host (if applicable): Selfhosted
- Pastebin of crashlogs or other relevant logs: https://pastebin.com/6uWDYpSX
- Other Relevant Data/Screenshots: none?
- Steps to Replicate: Have a large map with a large SQLite database
[x] I have looked at all other issues and this is not a duplicate
[x] I have been able to replicate this